mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-31 17:17:26 +00:00
abilities syntax has
-> implements
This commit is contained in:
parent
91e37293a2
commit
dbc0204532
21 changed files with 89 additions and 84 deletions
|
@ -10,9 +10,9 @@ Model position : {
|
|||
openSet : Set position,
|
||||
costs : Dict position F64,
|
||||
cameFrom : Dict position position,
|
||||
} | position has Hash & Eq
|
||||
} | position implements Hash & Eq
|
||||
|
||||
initialModel : position -> Model position | position has Hash & Eq
|
||||
initialModel : position -> Model position | position implements Hash & Eq
|
||||
initialModel = \start -> {
|
||||
evaluated: Set.empty {},
|
||||
openSet: Set.single start,
|
||||
|
@ -20,7 +20,7 @@ initialModel = \start -> {
|
|||
cameFrom: Dict.empty {},
|
||||
}
|
||||
|
||||
cheapestOpen : (position -> F64), Model position -> Result position {} | position has Hash & Eq
|
||||
cheapestOpen : (position -> F64), Model position -> Result position {} | position implements Hash & Eq
|
||||
cheapestOpen = \costFn, model ->
|
||||
model.openSet
|
||||
|> Set.toList
|
||||
|
@ -35,13 +35,13 @@ cheapestOpen = \costFn, model ->
|
|||
|> Result.map .position
|
||||
|> Result.mapErr (\_ -> {})
|
||||
|
||||
reconstructPath : Dict position position, position -> List position | position has Hash & Eq
|
||||
reconstructPath : Dict position position, position -> List position | position implements Hash & Eq
|
||||
reconstructPath = \cameFrom, goal ->
|
||||
when Dict.get cameFrom goal is
|
||||
Err _ -> []
|
||||
Ok next -> List.append (reconstructPath cameFrom next) goal
|
||||
|
||||
updateCost : position, position, Model position -> Model position | position has Hash & Eq
|
||||
updateCost : position, position, Model position -> Model position | position implements Hash & Eq
|
||||
updateCost = \current, neighbor, model ->
|
||||
newCameFrom =
|
||||
Dict.insert model.cameFrom neighbor current
|
||||
|
@ -70,7 +70,7 @@ updateCost = \current, neighbor, model ->
|
|||
else
|
||||
model
|
||||
|
||||
astar : (position, position -> F64), (position -> Set position), position, Model position -> Result (List position) {} | position has Hash & Eq
|
||||
astar : (position, position -> F64), (position -> Set position), position, Model position -> Result (List position) {} | position implements Hash & Eq
|
||||
astar = \costFn, moveFn, goal, model ->
|
||||
when cheapestOpen (\source -> costFn source goal) model is
|
||||
Err {} -> Err {}
|
||||
|
|
|
@ -80,7 +80,7 @@ impl AbilityMemberData<Resolved> {
|
|||
|
||||
/// Solved lambda sets for an ability member specialization. For example, if we have
|
||||
///
|
||||
/// Default has default : {} -[[] + a:default:1]-> a | a has Default
|
||||
/// Default has default : {} -[[] + a:default:1]-> a | a implements Default
|
||||
///
|
||||
/// A := {}
|
||||
/// default = \{} -[[closA]]-> @A {}
|
||||
|
@ -144,7 +144,7 @@ pub struct IAbilitiesStore<Phase: ResolvePhase> {
|
|||
///
|
||||
/// For example, in the program
|
||||
///
|
||||
/// Hash has hash : a -> U64 | a has Hash
|
||||
/// Hash has hash : a -> U64 | a implements Hash
|
||||
///
|
||||
/// Id := {} implements [Hash {hash: myHash}]
|
||||
/// myHash = \@Id n -> n
|
||||
|
@ -284,7 +284,7 @@ impl<Phase: ResolvePhase> IAbilitiesStore<Phase> {
|
|||
}
|
||||
|
||||
/// Finds the implementation key for a symbol specializing the ability member, if it specializes any.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a has Hash`.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a implements Hash`.
|
||||
/// Calling this with `hashId` would retrieve (hash, hashId).
|
||||
pub fn impl_key(&self, specializing_symbol: Symbol) -> Option<&ImplKey> {
|
||||
self.specialization_to_root.get(&specializing_symbol)
|
||||
|
@ -392,7 +392,7 @@ pub enum MarkError {
|
|||
impl IAbilitiesStore<Resolved> {
|
||||
/// Finds the symbol name and ability member definition for a symbol specializing the ability
|
||||
/// member, if it specializes any.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a has Hash`.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a implements Hash`.
|
||||
/// Calling this with `hashId` would retrieve the ability member data for `hash`, and what type
|
||||
/// `hashId` is specializing for.
|
||||
pub fn impl_key_and_def(
|
||||
|
|
|
@ -296,7 +296,7 @@ pub(crate) fn canonicalize_annotation(
|
|||
|
||||
let (annotation, region) = match annotation {
|
||||
TypeAnnotation::Where(annotation, clauses) => {
|
||||
// Add each "has" clause. The association of a variable to an ability will be saved on
|
||||
// Add each "implements" clause. The association of a variable to an ability will be saved on
|
||||
// `introduced_variables`, which we'll process later.
|
||||
for clause in clauses.iter() {
|
||||
let opt_err = canonicalize_has_clause(
|
||||
|
|
|
@ -480,7 +480,7 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
//
|
||||
// interface F imports [] exposes []
|
||||
//
|
||||
// Hello := {} has [Encoding.{ toEncoder }]
|
||||
// Hello := {} implements [Encoding.{ toEncoder }]
|
||||
//
|
||||
// toEncoder = \@Hello {} -> ...
|
||||
//
|
||||
|
@ -492,7 +492,7 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
//
|
||||
// interface F imports [Encoding.{ toEncoder }] exposes []
|
||||
//
|
||||
// Hello := {} has [Encoding.{ toEncoder }]
|
||||
// Hello := {} implements [Encoding.{ toEncoder }]
|
||||
//
|
||||
// toEncoder = \@Hello {} -> ...
|
||||
//
|
||||
|
@ -510,9 +510,9 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
// definition symbol, for example when the ability is defined in the same
|
||||
// module as an implementer:
|
||||
//
|
||||
// Eq has eq : a, a -> U64 | a has Eq
|
||||
// Eq has eq : a, a -> U64 | a implements Eq
|
||||
//
|
||||
// A := U8 has [Eq {eq}]
|
||||
// A := U8 implements [Eq {eq}]
|
||||
//
|
||||
// So, do a final check that the implementation symbol is not resolved directly
|
||||
// to the member.
|
||||
|
@ -749,8 +749,8 @@ fn canonicalize_opaque<'a>(
|
|||
// Did the user claim this implementation for a specialization of a different
|
||||
// type? e.g.
|
||||
//
|
||||
// A has [Hash {hash: myHash}]
|
||||
// B has [Hash {hash: myHash}]
|
||||
// A implements [Hash {hash: myHash}]
|
||||
// B implements [Hash {hash: myHash}]
|
||||
//
|
||||
// If so, that's an error and we drop the impl for this opaque type.
|
||||
let member_impl = match scope.abilities_store.impl_key(impl_symbol) {
|
||||
|
@ -1398,7 +1398,7 @@ fn resolve_abilities(
|
|||
}
|
||||
[..] => {
|
||||
// There is more than one variable bound to the member signature, so something like
|
||||
// Eq has eq : a, b -> Bool | a has Eq, b has Eq
|
||||
// Eq has eq : a, b -> Bool | a has Eq, b implements Eq
|
||||
// We have no way of telling what type implements a particular instance of Eq in
|
||||
// this case (a or b?), so disallow it.
|
||||
let span_has_clauses = Region::across_all(
|
||||
|
|
|
@ -76,7 +76,7 @@ pub enum Pattern {
|
|||
Underscore,
|
||||
|
||||
/// An identifier that marks a specialization of an ability member.
|
||||
/// For example, given an ability member definition `hash : a -> U64 | a has Hash`,
|
||||
/// For example, given an ability member definition `hash : a -> U64 | a implements Hash`,
|
||||
/// there may be the specialization `hash : Bool -> U64`. In this case we generate a
|
||||
/// new symbol for the specialized "hash" identifier.
|
||||
AbilityMemberSpecialization {
|
||||
|
|
|
@ -33,7 +33,7 @@ pub struct Scope {
|
|||
imports: Vec<(Ident, Symbol, Region)>,
|
||||
|
||||
/// Shadows of an ability member, for example a local specialization of `eq` for the ability
|
||||
/// member `Eq has eq : a, a -> Bool | a has Eq` gets a shadow symbol it can use for its
|
||||
/// member `Eq has eq : a, a -> Bool | a implements Eq` gets a shadow symbol it can use for its
|
||||
/// implementation.
|
||||
///
|
||||
/// Only one shadow of an ability member is permitted per scope.
|
||||
|
|
|
@ -63,7 +63,7 @@ fn wrap_in_decode_custom_decode_with(
|
|||
|
||||
// Decode.decodeWith bytes inner_decoder fmt : DecodeResult val
|
||||
let (decode_with_call, decode_with_result_var) = {
|
||||
// Decode.decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt has DecoderFormatting
|
||||
// Decode.decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt implements DecoderFormatting
|
||||
let decode_with_type = env.import_builtin_symbol_var(Symbol::DECODE_DECODE_WITH);
|
||||
|
||||
// Decode.decodeWith : bytes, inner_decoder, fmt -> DecoderResult (List val)
|
||||
|
@ -80,7 +80,7 @@ fn wrap_in_decode_custom_decode_with(
|
|||
)),
|
||||
);
|
||||
|
||||
// List U8, Decoder val fmt, fmt -> DecodeResult val | fmt has DecoderFormatting
|
||||
// List U8, Decoder val fmt, fmt -> DecodeResult val | fmt implements DecoderFormatting
|
||||
// ~ bytes, Decoder (List elem) fmt, fmt -> DecoderResult (List val)
|
||||
env.unify(decode_with_type, this_decode_with_fn_var);
|
||||
|
||||
|
@ -169,7 +169,7 @@ fn wrap_in_decode_custom_decode_with(
|
|||
|
||||
// Decode.custom \bytes, fmt -> Decode.decodeWith bytes inner_decoder fmt
|
||||
let (decode_custom_call, decoder_var) = {
|
||||
// (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
// (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt implements DecoderFormatting
|
||||
let decode_custom_type = env.import_builtin_symbol_var(Symbol::DECODE_CUSTOM);
|
||||
|
||||
// (List U8, fmt -> DecodeResult (List elem)) -> Decoder (List elem) fmt
|
||||
|
@ -185,7 +185,7 @@ fn wrap_in_decode_custom_decode_with(
|
|||
)),
|
||||
);
|
||||
|
||||
// (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
// (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt implements DecoderFormatting
|
||||
// ~ (List U8, fmt -> DecodeResult (List elem)) -> Decoder (List elem) fmt
|
||||
env.unify(decode_custom_type, this_decode_custom_fn_var);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::util::Env;
|
|||
pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable) {
|
||||
// Build
|
||||
//
|
||||
// def_symbol : Decoder (List elem) fmt | elem has Decoding, fmt has DecoderFormatting
|
||||
// def_symbol : Decoder (List elem) fmt | elem has Decoding, fmt implements DecoderFormatting
|
||||
// def_symbol = Decode.custom \bytes, fmt -> Decode.decodeWith bytes (Decode.list Decode.decoder) fmt
|
||||
//
|
||||
// NB: reduction to `Decode.list Decode.decoder` is not possible to the HRR.
|
||||
|
@ -27,10 +27,10 @@ pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable
|
|||
// List elem
|
||||
let elem_var = env.subs.fresh_unnamed_flex_var();
|
||||
|
||||
// Decode.decoder : Decoder elem fmt | elem has Decoding, fmt has EncoderFormatting
|
||||
// Decode.decoder : Decoder elem fmt | elem has Decoding, fmt implements EncoderFormatting
|
||||
let (elem_decoder, elem_decoder_var) = {
|
||||
// build `Decode.decoder : Decoder elem fmt` type
|
||||
// Decoder val fmt | val has Decoding, fmt has EncoderFormatting
|
||||
// Decoder val fmt | val has Decoding, fmt implements EncoderFormatting
|
||||
let elem_decoder_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODER);
|
||||
|
||||
// set val ~ elem
|
||||
|
@ -52,7 +52,7 @@ pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable
|
|||
};
|
||||
|
||||
// Build `Decode.list Decode.decoder` type
|
||||
// Decoder val fmt -[uls]-> Decoder (List val) fmt | fmt has DecoderFormatting
|
||||
// Decoder val fmt -[uls]-> Decoder (List val) fmt | fmt implements DecoderFormatting
|
||||
let decode_list_fn_var = env.import_builtin_symbol_var(Symbol::DECODE_LIST);
|
||||
|
||||
// Decoder elem fmt -a-> b
|
||||
|
@ -68,7 +68,7 @@ pub(crate) fn decoder(env: &mut Env<'_>, _def_symbol: Symbol) -> (Expr, Variable
|
|||
)),
|
||||
);
|
||||
|
||||
// Decoder val fmt -[uls]-> Decoder (List val) fmt | fmt has DecoderFormatting
|
||||
// Decoder val fmt -[uls]-> Decoder (List val) fmt | fmt implements DecoderFormatting
|
||||
// ~ Decoder elem fmt -a -> b
|
||||
env.unify(decode_list_fn_var, this_decode_list_fn_var);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ use super::wrap_in_decode_custom_decode_with;
|
|||
/// we'd like to generate an impl like
|
||||
///
|
||||
/// ```roc
|
||||
/// decoder : Decoder {first: a, second: b} fmt | a has Decoding, b has Decoding, fmt has DecoderFormatting
|
||||
/// decoder : Decoder {first: a, second: b} fmt | a implements Decoding, b implements Decoding, fmt implements DecoderFormatting
|
||||
/// decoder =
|
||||
/// initialState : {f0: Result a [NoField], f1: Result b [NoField]}
|
||||
/// initialState = {f0: Err NoField, f1: Err NoField}
|
||||
|
|
|
@ -28,7 +28,7 @@ use super::wrap_in_decode_custom_decode_with;
|
|||
/// we'd like to generate an impl like
|
||||
///
|
||||
/// ```roc
|
||||
/// decoder : Decoder (a, b) fmt | a has Decoding, b has Decoding, fmt has DecoderFormatting
|
||||
/// decoder : Decoder (a, b) fmt | a implements Decoding, b implements Decoding, fmt implements DecoderFormatting
|
||||
/// decoder =
|
||||
/// initialState : {e0: Result a [NoElem], e1: Result b [NoElem]}
|
||||
/// initialState = {e0: Err NoElem, e1: Err NoElem}
|
||||
|
|
|
@ -121,7 +121,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
);
|
||||
|
||||
// build `toEncoder elem` type
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TO_ENCODER);
|
||||
|
||||
// elem -[clos]-> t1
|
||||
|
@ -136,11 +136,11 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
)),
|
||||
);
|
||||
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ elem -[clos]-> t1
|
||||
env.unify(to_encoder_fn_var, elem_to_encoder_fn_var);
|
||||
|
||||
// toEncoder : (typeof rcd.a) -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// toEncoder : (typeof rcd.a) -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_var = AbilityMember(Symbol::ENCODE_TO_ENCODER, None, elem_to_encoder_fn_var);
|
||||
let to_encoder_fn = Box::new((
|
||||
to_encoder_fn_var,
|
||||
|
@ -201,7 +201,7 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
});
|
||||
|
||||
// build `Encode.list lst (\elem -> Encode.toEncoder elem)` type
|
||||
// List e, (e -> Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// List e, (e -> Encoder fmt) -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_list_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_LIST);
|
||||
|
||||
// List elem, to_elem_encoder_fn_var -[clos]-> t1
|
||||
|
@ -218,11 +218,11 @@ fn to_encoder_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
|
|||
)),
|
||||
);
|
||||
|
||||
// List e, (e -> Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// List e, (e -> Encoder fmt) -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ List elem, to_elem_encoder_fn_var -[clos]-> t1
|
||||
env.unify(encode_list_fn_var, this_encode_list_fn_var);
|
||||
|
||||
// Encode.list : List elem, to_elem_encoder_fn_var -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// Encode.list : List elem, to_elem_encoder_fn_var -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_list = AbilityMember(Symbol::ENCODE_LIST, None, this_encode_list_fn_var);
|
||||
let encode_list_fn = Box::new((
|
||||
this_encode_list_fn_var,
|
||||
|
@ -340,7 +340,7 @@ fn to_encoder_record(
|
|||
};
|
||||
|
||||
// build `toEncoder rcd.a` type
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TO_ENCODER);
|
||||
|
||||
// (typeof rcd.a) -[clos]-> t1
|
||||
|
@ -355,11 +355,11 @@ fn to_encoder_record(
|
|||
)),
|
||||
);
|
||||
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ (typeof rcd.a) -[clos]-> t1
|
||||
env.unify(to_encoder_fn_var, this_to_encoder_fn_var);
|
||||
|
||||
// toEncoder : (typeof rcd.a) -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// toEncoder : (typeof rcd.a) -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_var = AbilityMember(Symbol::ENCODE_TO_ENCODER, None, to_encoder_fn_var);
|
||||
let to_encoder_fn = Box::new((
|
||||
to_encoder_fn_var,
|
||||
|
@ -420,7 +420,7 @@ fn to_encoder_record(
|
|||
};
|
||||
|
||||
// build `Encode.record [ { key: .., value: ..}, .. ]` type
|
||||
// List { key : Str, value : Encoder fmt } -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// List { key : Str, value : Encoder fmt } -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_record_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_RECORD);
|
||||
|
||||
// fields_list_var -[clos]-> t1
|
||||
|
@ -437,11 +437,11 @@ fn to_encoder_record(
|
|||
)),
|
||||
);
|
||||
|
||||
// List { key : Str, value : Encoder fmt } -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// List { key : Str, value : Encoder fmt } -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ fields_list_var -[clos]-> t1
|
||||
env.unify(encode_record_fn_var, this_encode_record_fn_var);
|
||||
|
||||
// Encode.record : fields_list_var -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// Encode.record : fields_list_var -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_record_var = AbilityMember(Symbol::ENCODE_RECORD, None, encode_record_fn_var);
|
||||
let encode_record_fn = Box::new((
|
||||
encode_record_fn_var,
|
||||
|
@ -543,7 +543,7 @@ fn to_encoder_tuple(
|
|||
};
|
||||
|
||||
// build `toEncoder tup.0` type
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TO_ENCODER);
|
||||
|
||||
// (typeof tup.0) -[clos]-> t1
|
||||
|
@ -558,11 +558,11 @@ fn to_encoder_tuple(
|
|||
)),
|
||||
);
|
||||
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ (typeof tup.0) -[clos]-> t1
|
||||
env.unify(to_encoder_fn_var, this_to_encoder_fn_var);
|
||||
|
||||
// toEncoder : (typeof tup.0) -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// toEncoder : (typeof tup.0) -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_var = AbilityMember(Symbol::ENCODE_TO_ENCODER, None, to_encoder_fn_var);
|
||||
let to_encoder_fn = Box::new((
|
||||
to_encoder_fn_var,
|
||||
|
@ -603,7 +603,7 @@ fn to_encoder_tuple(
|
|||
};
|
||||
|
||||
// build `Encode.tuple [ toEncoder tup.0, toEncoder tup.1 ]` type
|
||||
// List (Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// List (Encoder fmt) -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_tuple_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TUPLE);
|
||||
|
||||
// elem_encoders_list_var -[clos]-> t1
|
||||
|
@ -620,11 +620,11 @@ fn to_encoder_tuple(
|
|||
)),
|
||||
);
|
||||
|
||||
// List (Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// List (Encoder fmt) -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ elem_encoders_list_var -[clos]-> t1
|
||||
env.unify(encode_tuple_fn_var, this_encode_tuple_fn_var);
|
||||
|
||||
// Encode.tuple : elem_encoders_list_var -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// Encode.tuple : elem_encoders_list_var -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_tuple_var = AbilityMember(Symbol::ENCODE_TUPLE, None, encode_tuple_fn_var);
|
||||
let encode_tuple_fn = Box::new((
|
||||
encode_tuple_fn_var,
|
||||
|
@ -741,7 +741,7 @@ fn to_encoder_tag_union(
|
|||
.zip(payload_vars.iter())
|
||||
.map(|(&sym, &sym_var)| {
|
||||
// build `toEncoder v1` type
|
||||
// expected: val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// expected: val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_fn_var =
|
||||
env.import_builtin_symbol_var(Symbol::ENCODE_TO_ENCODER);
|
||||
|
||||
|
@ -759,11 +759,11 @@ fn to_encoder_tag_union(
|
|||
)),
|
||||
);
|
||||
|
||||
// val -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// val -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ t1 -[clos]-> t'
|
||||
env.unify(to_encoder_fn_var, this_to_encoder_fn_var);
|
||||
|
||||
// toEncoder : t1 -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// toEncoder : t1 -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let to_encoder_var =
|
||||
AbilityMember(Symbol::ENCODE_TO_ENCODER, None, this_to_encoder_fn_var);
|
||||
let to_encoder_fn = Box::new((
|
||||
|
@ -802,7 +802,7 @@ fn to_encoder_tag_union(
|
|||
};
|
||||
|
||||
// build `Encode.tag "A" [ ... ]` type
|
||||
// expected: Str, List (Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// expected: Str, List (Encoder fmt) -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_tag_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_TAG);
|
||||
|
||||
// wanted: Str, List whole_encoders_var -[clos]-> t'
|
||||
|
@ -821,11 +821,11 @@ fn to_encoder_tag_union(
|
|||
)),
|
||||
);
|
||||
|
||||
// Str, List (Encoder fmt) -[uls]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// Str, List (Encoder fmt) -[uls]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ Str, List whole_encoders_var -[clos]-> t'
|
||||
env.unify(encode_tag_fn_var, this_encode_tag_fn_var);
|
||||
|
||||
// Encode.tag : Str, List whole_encoders_var -[clos]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// Encode.tag : Str, List whole_encoders_var -[clos]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
let encode_tag_var = AbilityMember(Symbol::ENCODE_TAG, None, this_encode_tag_fn_var);
|
||||
let encode_tag_fn = Box::new((
|
||||
this_encode_tag_fn_var,
|
||||
|
@ -954,15 +954,15 @@ fn wrap_in_encode_custom(
|
|||
let bytes_sym = env.new_symbol("bytes");
|
||||
let bytes_var = Variable::LIST_U8;
|
||||
|
||||
// fmt: fmt | fmt has EncoderFormatting
|
||||
// fmt: fmt | fmt implements EncoderFormatting
|
||||
let fmt_sym = env.new_symbol("fmt");
|
||||
let fmt_var = env.subs.fresh_unnamed_flex_var();
|
||||
|
||||
// build `Encode.appendWith bytes encoder fmt` type
|
||||
// expected: Encode.appendWith : List U8, Encoder fmt, fmt -[appendWith]-> List U8 | fmt has EncoderFormatting
|
||||
// expected: Encode.appendWith : List U8, Encoder fmt, fmt -[appendWith]-> List U8 | fmt implements EncoderFormatting
|
||||
let append_with_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_APPEND_WITH);
|
||||
|
||||
// wanted: Encode.appendWith : List U8, encoder_var, fmt -[clos]-> List U8 | fmt has EncoderFormatting
|
||||
// wanted: Encode.appendWith : List U8, encoder_var, fmt -[clos]-> List U8 | fmt implements EncoderFormatting
|
||||
let this_append_with_args_var_slice =
|
||||
VariableSubsSlice::insert_into_subs(env.subs, [Variable::LIST_U8, encoder_var, fmt_var]);
|
||||
let this_append_with_clos_var = env.subs.fresh_unnamed_flex_var(); // -[clos]->
|
||||
|
@ -975,11 +975,11 @@ fn wrap_in_encode_custom(
|
|||
)),
|
||||
);
|
||||
|
||||
// List U8, Encoder fmt, fmt -[appendWith]-> List U8 | fmt has EncoderFormatting
|
||||
// ~ List U8, encoder_var, fmt -[clos]-> List U8 | fmt has EncoderFormatting
|
||||
// List U8, Encoder fmt, fmt -[appendWith]-> List U8 | fmt implements EncoderFormatting
|
||||
// ~ List U8, encoder_var, fmt -[clos]-> List U8 | fmt implements EncoderFormatting
|
||||
env.unify(append_with_fn_var, this_append_with_fn_var);
|
||||
|
||||
// Encode.appendWith : List U8, encoder_var, fmt -[appendWith]-> List U8 | fmt has EncoderFormatting
|
||||
// Encode.appendWith : List U8, encoder_var, fmt -[appendWith]-> List U8 | fmt implements EncoderFormatting
|
||||
let append_with_fn = Box::new((
|
||||
this_append_with_fn_var,
|
||||
Loc::at_zero(Var(Symbol::ENCODE_APPEND_WITH, this_append_with_fn_var)),
|
||||
|
@ -1050,7 +1050,7 @@ fn wrap_in_encode_custom(
|
|||
// Build
|
||||
// Encode.custom \bytes, fmt -> Encode.appendWith bytes encoder fmt
|
||||
//
|
||||
// expected: Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting
|
||||
// expected: Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt implements EncoderFormatting
|
||||
let custom_fn_var = env.import_builtin_symbol_var(Symbol::ENCODE_CUSTOM);
|
||||
|
||||
// wanted: Encode.custom : fn_var -[clos]-> t'
|
||||
|
@ -1066,11 +1066,11 @@ fn wrap_in_encode_custom(
|
|||
)),
|
||||
);
|
||||
|
||||
// (List U8, fmt -> List U8) -[..]-> Encoder fmt | fmt has EncoderFormatting
|
||||
// (List U8, fmt -> List U8) -[..]-> Encoder fmt | fmt implements EncoderFormatting
|
||||
// ~ fn_var -[clos]-> t'
|
||||
env.unify(custom_fn_var, this_custom_fn_var);
|
||||
|
||||
// Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting
|
||||
// Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt implements EncoderFormatting
|
||||
let custom_fn = Box::new((
|
||||
this_custom_fn_var,
|
||||
Loc::at_zero(Var(Symbol::ENCODE_CUSTOM, this_custom_fn_var)),
|
||||
|
|
|
@ -75,7 +75,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec<Lowercase>) -> (V
|
|||
|
||||
// Now, a hasher for this record is
|
||||
//
|
||||
// hash_rcd : hasher, { f1: t1, ..., fn: tn } -> hasher | hasher has Hasher
|
||||
// hash_rcd : hasher, { f1: t1, ..., fn: tn } -> hasher | hasher implements Hasher
|
||||
// hash_rcd = \hasher, rcd ->
|
||||
// Hash.hash (
|
||||
// Hash.hash
|
||||
|
@ -144,7 +144,7 @@ fn hash_tuple(env: &mut Env<'_>, fn_name: Symbol, arity: u32) -> (Variable, Expr
|
|||
|
||||
// Now, a hasher for this tuple is
|
||||
//
|
||||
// hash_tup : hasher, (t1, ..., tn) -> hasher | hasher has Hasher
|
||||
// hash_tup : hasher, (t1, ..., tn) -> hasher | hasher implements Hasher
|
||||
// hash_tup = \hasher, tup ->
|
||||
// Hash.hash (
|
||||
// Hash.hash
|
||||
|
@ -227,7 +227,7 @@ fn hash_tag_union(
|
|||
|
||||
// Now, a hasher for this tag union is
|
||||
//
|
||||
// hash_union : hasher, [ A t11 .. t1n, ..., Q tq1 .. tqm ] -> hasher | hasher has Hasher
|
||||
// hash_union : hasher, [ A t11 .. t1n, ..., Q tq1 .. tqm ] -> hasher | hasher implements Hasher
|
||||
// hash_union = \hasher, union ->
|
||||
// when union is
|
||||
// A x11 .. x1n -> Hash.hash (... (Hash.hash (Hash.uN hasher 0) x11) ...) x1n
|
||||
|
@ -393,7 +393,7 @@ fn hash_newtype_tag_union(
|
|||
|
||||
// Now, a hasher for this tag union is
|
||||
//
|
||||
// hash_union : hasher, [ A t1 .. tn ] -> hasher | hasher has Hasher
|
||||
// hash_union : hasher, [ A t1 .. tn ] -> hasher | hasher implements Hasher
|
||||
// hash_union = \hasher, A x1 .. xn ->
|
||||
// Hash.hash (... (Hash.hash discrHasher x1) ...) xn
|
||||
let hasher_sym = env.new_symbol("hasher");
|
||||
|
@ -462,7 +462,7 @@ fn call_hash_ability_member(
|
|||
|
||||
// build `member ...` function type. `member` here is `Hash.hash` or `Hash.addU16`.
|
||||
//
|
||||
// hasher, val -[uls]-> hasher | hasher has Hasher, val has Hash
|
||||
// hasher, val -[uls]-> hasher | hasher has Hasher, val implements Hash
|
||||
let exposed_hash_fn_var = env.import_builtin_symbol_var(member);
|
||||
|
||||
// (typeof body), (typeof field) -[clos]-> hasher_result
|
||||
|
@ -479,11 +479,11 @@ fn call_hash_ability_member(
|
|||
)),
|
||||
);
|
||||
|
||||
// hasher, val -[uls]-> hasher | hasher has Hasher, val has Hash
|
||||
// hasher, val -[uls]-> hasher | hasher has Hasher, val implements Hash
|
||||
// ~ (typeof body), (typeof field) -[clos]-> hasher_result
|
||||
env.unify(exposed_hash_fn_var, this_hash_fn_var);
|
||||
|
||||
// Hash.hash : hasher, (typeof field) -[clos]-> hasher | hasher has Hasher, (typeof field) has Hash
|
||||
// Hash.hash : hasher, (typeof field) -[clos]-> hasher | hasher has Hasher, (typeof field) implements Hash
|
||||
let hash_fn_head = Expr::AbilityMember(member, None, this_hash_fn_var);
|
||||
let hash_fn_data = Box::new((
|
||||
this_hash_fn_var,
|
||||
|
|
|
@ -130,7 +130,7 @@ impl Env<'_> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
// Since we're doing `{foo} ~ a | a has Encoding`, we may see "lambda sets to
|
||||
// Since we're doing `{foo} ~ a | a implements Encoding`, we may see "lambda sets to
|
||||
// specialize" for e.g. `{foo}:toEncoder:1`, but these are actually just the
|
||||
// specialization lambda sets, so we don't need to do any extra work!
|
||||
//
|
||||
|
|
|
@ -647,7 +647,7 @@ impl<'a> Formattable for Tag<'a> {
|
|||
|
||||
impl<'a> Formattable for ImplementsClause<'a> {
|
||||
fn is_multiline(&self) -> bool {
|
||||
// No, always put abilities in a "has" clause on one line
|
||||
// No, always put abilities in an "implements" clause on one line
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -1106,8 +1106,13 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
|||
*******************************************************************/
|
||||
|
||||
fn expr_literal(&mut self, lit: &Literal<'a>, storage: &StoredValue) {
|
||||
let invalid_error =
|
||||
|| internal_error!("Literal value {:?} has invalid storage {:?}", lit, storage);
|
||||
let invalid_error = || {
|
||||
internal_error!(
|
||||
"Literal value {:?} implements invalid storage {:?}",
|
||||
lit,
|
||||
storage
|
||||
)
|
||||
};
|
||||
|
||||
match storage {
|
||||
StoredValue::VirtualMachineStack { value_type, .. } => {
|
||||
|
|
|
@ -3172,7 +3172,7 @@ fn update<'a>(
|
|||
// # Default module
|
||||
// interface Default exposes [default, getDefault]
|
||||
//
|
||||
// Default has default : {} -> a | a has Default
|
||||
// Default has default : {} -> a | a implements Default
|
||||
//
|
||||
// getDefault = \{} -> default {}
|
||||
//
|
||||
|
@ -4632,7 +4632,7 @@ fn build_header<'a>(
|
|||
// created an IdentId for this, when it was imported exposed
|
||||
// in a dependent module.
|
||||
//
|
||||
// For example, if module A has [B.{ foo }], then
|
||||
// For example, if module A implements [B.{ foo }], then
|
||||
// when we get here for B, `foo` will already have
|
||||
// an IdentId. We must reuse that!
|
||||
let ident_id = ident_ids.get_or_insert(loc_exposed.value.as_str());
|
||||
|
@ -4656,7 +4656,7 @@ fn build_header<'a>(
|
|||
// created an IdentId for this, when it was imported exposed
|
||||
// in a dependent module.
|
||||
//
|
||||
// For example, if module A has [B.{ foo }], then
|
||||
// For example, if module A implements [B.{ foo }], then
|
||||
// when we get here for B, `foo` will already have
|
||||
// an IdentId. We must reuse that!
|
||||
let ident_id = ident_ids.get_or_insert(loc_name.value.as_str());
|
||||
|
|
|
@ -739,7 +739,7 @@ trait DerivableVisitor {
|
|||
) {
|
||||
// TODO: currently, just we suppose the presence of a flex var may
|
||||
// include more or less things which we can derive. But, we should
|
||||
// instead recurse here, and add a `t ~ u | u has Decode` constraint as needed.
|
||||
// instead recurse here, and add a `t ~ u | u implements Decode` constraint as needed.
|
||||
stack.push(ext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2510,7 +2510,7 @@ impl AmbientFunctionPolicy {
|
|||
}),
|
||||
Content::FlexVar(_) => {
|
||||
// Something like
|
||||
// Encoder fmt <a> : List U8, fmt -a-> List U8 | fmt has EncoderFormatting
|
||||
// Encoder fmt <a> : List U8, fmt -a-> List U8 | fmt implements EncoderFormatting
|
||||
// THEORY: Replace these with empty lambda sets. They will unify the same as a flex
|
||||
// var does, but allows us to record the ambient function properly.
|
||||
Content::LambdaSet(LambdaSet {
|
||||
|
|
|
@ -136,8 +136,8 @@ fn find_names_needed(
|
|||
if !root_appearances.contains_key(&root) {
|
||||
roots.push(root);
|
||||
}
|
||||
// Able vars are always printed at least twice (in the signature, and in the "has"
|
||||
// clause set).
|
||||
// Able vars are always printed at least twice (in the signature, and in the
|
||||
// "implements" clause set).
|
||||
root_appearances.insert(root, Appearances::Multiple);
|
||||
}
|
||||
RecursionVar {
|
||||
|
|
|
@ -1760,7 +1760,7 @@ pub enum Type {
|
|||
}
|
||||
|
||||
/// A lambda set under an arrow in a ability member signature. For example, in
|
||||
/// Default has default : {} -> a | a has Default
|
||||
/// Default has default : {} -> a | a implements Default
|
||||
/// the unspecialized lambda set for the arrow "{} -> a" would be `a:default:1`.
|
||||
///
|
||||
/// Lambda sets in member signatures are never known until those members are specialized at a
|
||||
|
|
|
@ -1302,7 +1302,7 @@ fn extract_specialization_lambda_set<M: MetaCollector>(
|
|||
// lambda set does not line up with one required by the ability member prototype.
|
||||
// As an example, consider
|
||||
//
|
||||
// Q := [ F (Str -> Str) ] has [Eq {isEq}]
|
||||
// Q := [ F (Str -> Str) ] implements [Eq {isEq}]
|
||||
//
|
||||
// isEq = \@Q _, @Q _ -> Bool.false
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue