mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Merge remote-tracking branch 'origin/trunk' into low-level-ops
This commit is contained in:
commit
1cd49689c2
29 changed files with 1630 additions and 440 deletions
|
@ -10,7 +10,7 @@ use crate::pattern::{bindings_from_patterns, canonicalize_pattern, Pattern};
|
|||
use crate::procedure::References;
|
||||
use crate::scope::Scope;
|
||||
use roc_collections::all::{default_hasher, ImMap, ImSet, MutMap, MutSet, SendMap};
|
||||
use roc_module::ident::{Ident, Lowercase};
|
||||
use roc_module::ident::Lowercase;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_parse::ast;
|
||||
use roc_parse::pattern::PatternType;
|
||||
|
@ -41,9 +41,7 @@ pub struct Annotation {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct CanDefs {
|
||||
// TODO don't store the Ident in here (lots of cloning!) - instead,
|
||||
// make refs_by_symbol be something like MutMap<Symbol, (Region, References)>
|
||||
pub refs_by_symbol: MutMap<Symbol, (Located<Ident>, References)>,
|
||||
pub refs_by_symbol: MutMap<Symbol, (Region, References)>,
|
||||
pub can_defs_by_symbol: MutMap<Symbol, Def>,
|
||||
pub aliases: SendMap<Symbol, Alias>,
|
||||
}
|
||||
|
@ -79,7 +77,10 @@ enum PendingDef<'a> {
|
|||
ann: &'a Located<ast::TypeAnnotation<'a>>,
|
||||
},
|
||||
|
||||
ShadowedAlias,
|
||||
/// An invalid alias, that is ignored in the rest of the pipeline
|
||||
/// e.g. a shadowed alias, or a definition like `MyAlias 1 : Int`
|
||||
/// with an incorrect pattern
|
||||
InvalidAlias,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
@ -87,11 +88,8 @@ enum PendingDef<'a> {
|
|||
pub enum Declaration {
|
||||
Declare(Def),
|
||||
DeclareRec(Vec<Def>),
|
||||
InvalidCycle(
|
||||
Vec<Located<Ident>>,
|
||||
Vec<(Region /* pattern */, Region /* expr */)>,
|
||||
),
|
||||
Builtin(Def),
|
||||
InvalidCycle(Vec<Symbol>, Vec<(Region /* pattern */, Region /* expr */)>),
|
||||
}
|
||||
|
||||
impl Declaration {
|
||||
|
@ -155,7 +153,7 @@ pub fn canonicalize_defs<'a>(
|
|||
match iter.peek() {
|
||||
Some(Located {
|
||||
value: Body(body_pattern, body_expr),
|
||||
..
|
||||
region: body_region,
|
||||
}) => {
|
||||
if pattern.value.equivalent(&body_pattern.value) {
|
||||
iter.next();
|
||||
|
@ -169,8 +167,20 @@ pub fn canonicalize_defs<'a>(
|
|||
&mut scope,
|
||||
pattern_type,
|
||||
)
|
||||
} else if loc_def.region.lines_between(body_region) > 1 {
|
||||
// there is a line of whitespace between the annotation and the body
|
||||
// treat annotation and body separately
|
||||
to_pending_def(env, var_store, &loc_def.value, &mut scope, pattern_type)
|
||||
} else {
|
||||
panic!("TODO gracefully handle the case where a type annotation appears immediately before a body def, but the patterns are different. This should be an error; put a newline or comment between them!");
|
||||
// the pattern of the annotation does not match the pattern of the body directly below it
|
||||
env.problems.push(Problem::SignatureDefMismatch {
|
||||
annotation_pattern: pattern.region,
|
||||
def_pattern: body_pattern.region,
|
||||
});
|
||||
|
||||
// both the annotation and definition are skipped!
|
||||
iter.next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => to_pending_def(env, var_store, &loc_def.value, &mut scope, pattern_type),
|
||||
|
@ -551,17 +561,18 @@ pub fn sort_can_defs(
|
|||
|
||||
if is_invalid_cycle {
|
||||
// We want to show the entire cycle in the error message, so expand it out.
|
||||
let mut loc_idents_in_cycle: Vec<Located<Ident>> = Vec::new();
|
||||
let mut loc_symbols = Vec::new();
|
||||
|
||||
for symbol in cycle {
|
||||
let refs = refs_by_symbol.get(&symbol).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Symbol not found in refs_by_symbol: {:?} - refs_by_symbol was: {:?}",
|
||||
symbol, refs_by_symbol
|
||||
)
|
||||
});
|
||||
|
||||
loc_idents_in_cycle.push(refs.0.clone());
|
||||
match refs_by_symbol.get(&symbol) {
|
||||
None => unreachable!(
|
||||
r#"Symbol `{:?}` not found in refs_by_symbol! refs_by_symbol was: {:?}"#,
|
||||
symbol, refs_by_symbol
|
||||
),
|
||||
Some((region, _)) => {
|
||||
loc_symbols.push(Located::at(*region, symbol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut regions = Vec::with_capacity(can_defs_by_symbol.len());
|
||||
|
@ -569,16 +580,19 @@ pub fn sort_can_defs(
|
|||
regions.push((def.loc_pattern.region, def.loc_expr.region));
|
||||
}
|
||||
|
||||
// Sort them to make the report more helpful.
|
||||
loc_idents_in_cycle.sort();
|
||||
// Sort them by line number to make the report more helpful.
|
||||
loc_symbols.sort();
|
||||
regions.sort();
|
||||
|
||||
let symbols_in_cycle: Vec<Symbol> =
|
||||
loc_symbols.into_iter().map(|s| s.value).collect();
|
||||
|
||||
problems.push(Problem::RuntimeError(RuntimeError::CircularDef(
|
||||
loc_idents_in_cycle.clone(),
|
||||
symbols_in_cycle.clone(),
|
||||
regions.clone(),
|
||||
)));
|
||||
|
||||
declarations.push(Declaration::InvalidCycle(loc_idents_in_cycle, regions));
|
||||
declarations.push(Declaration::InvalidCycle(symbols_in_cycle, regions));
|
||||
} else {
|
||||
// slightly inefficient, because we know this becomes exactly one DeclareRec already
|
||||
group_to_declaration(
|
||||
|
@ -711,6 +725,7 @@ fn pattern_to_vars_by_symbol(
|
|||
| FloatLiteral(_)
|
||||
| StrLiteral(_)
|
||||
| Underscore
|
||||
| MalformedPattern(_, _)
|
||||
| UnsupportedPattern(_) => {}
|
||||
|
||||
Shadowed(_, _) => {}
|
||||
|
@ -727,7 +742,7 @@ fn canonicalize_pending_def<'a>(
|
|||
scope: &mut Scope,
|
||||
can_defs_by_symbol: &mut MutMap<Symbol, Def>,
|
||||
var_store: &mut VarStore,
|
||||
refs_by_symbol: &mut MutMap<Symbol, (Located<Ident>, References)>,
|
||||
refs_by_symbol: &mut MutMap<Symbol, (Region, References)>,
|
||||
aliases: &mut SendMap<Symbol, Alias>,
|
||||
) -> Output {
|
||||
use PendingDef::*;
|
||||
|
@ -893,9 +908,8 @@ fn canonicalize_pending_def<'a>(
|
|||
.union(&can_ann.introduced_variables);
|
||||
}
|
||||
|
||||
ShadowedAlias => {
|
||||
// Since this alias was shadowed, it gets ignored and has no
|
||||
// effect on the output.
|
||||
InvalidAlias => {
|
||||
// invalid aliases (shadowed, incorrect patterns) get ignored
|
||||
}
|
||||
TypedBody(loc_pattern, loc_can_pattern, loc_ann, loc_expr) => {
|
||||
let ann =
|
||||
|
@ -995,7 +1009,7 @@ fn canonicalize_pending_def<'a>(
|
|||
|
||||
// Store the referenced locals in the refs_by_symbol map, so we can later figure out
|
||||
// which defined names reference each other.
|
||||
for (ident, (symbol, region)) in scope.idents() {
|
||||
for (_, (symbol, region)) in scope.idents() {
|
||||
if !vars_by_symbol.contains_key(&symbol) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1010,16 +1024,7 @@ fn canonicalize_pending_def<'a>(
|
|||
can_output.references.clone()
|
||||
};
|
||||
|
||||
refs_by_symbol.insert(
|
||||
*symbol,
|
||||
(
|
||||
Located {
|
||||
value: ident.clone(),
|
||||
region: *region,
|
||||
},
|
||||
refs,
|
||||
),
|
||||
);
|
||||
refs_by_symbol.insert(*symbol, (*region, refs));
|
||||
|
||||
can_defs_by_symbol.insert(
|
||||
*symbol,
|
||||
|
@ -1140,23 +1145,7 @@ fn canonicalize_pending_def<'a>(
|
|||
can_output.references.clone()
|
||||
};
|
||||
|
||||
let ident = env
|
||||
.ident_ids
|
||||
.get_name(symbol.ident_id())
|
||||
.unwrap_or_else(|| {
|
||||
panic!("Could not find {:?} in env.ident_ids", symbol);
|
||||
});
|
||||
|
||||
refs_by_symbol.insert(
|
||||
symbol,
|
||||
(
|
||||
Located {
|
||||
value: ident.clone().into(),
|
||||
region,
|
||||
},
|
||||
refs,
|
||||
),
|
||||
);
|
||||
refs_by_symbol.insert(symbol, (region, refs));
|
||||
|
||||
can_defs_by_symbol.insert(
|
||||
symbol,
|
||||
|
@ -1363,7 +1352,13 @@ fn to_pending_def<'a>(
|
|||
});
|
||||
}
|
||||
_ => {
|
||||
panic!("TODO gracefully handle an invalid pattern appearing where a type alias rigid var should be.");
|
||||
// any other pattern in this position is a syntax error.
|
||||
env.problems.push(Problem::InvalidAliasRigid {
|
||||
alias_name: symbol,
|
||||
region: loc_var.region,
|
||||
});
|
||||
|
||||
return PendingDef::InvalidAlias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1384,7 +1379,7 @@ fn to_pending_def<'a>(
|
|||
shadow: loc_shadowed_symbol,
|
||||
});
|
||||
|
||||
PendingDef::ShadowedAlias
|
||||
PendingDef::InvalidAlias
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue