From 0f289ed712c833a3cf0410d56dcfb663382e6ab5 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 19 May 2023 21:13:33 -0400 Subject: [PATCH 01/55] add word10 fn --- crates/compiler/parse/src/parser.rs | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/crates/compiler/parse/src/parser.rs b/crates/compiler/parse/src/parser.rs index 385dea9f406..ec6b6186064 100644 --- a/crates/compiler/parse/src/parser.rs +++ b/crates/compiler/parse/src/parser.rs @@ -1608,6 +1608,48 @@ where } } +pub fn word10<'a, ToError, E>( + word_1: u8, + word_2: u8, + word_3: u8, + word_4: u8, + word_5: u8, + word_6: u8, + word_7: u8, + word_8: u8, + word_9: u8, + word_10: u8, + to_error: ToError, +) -> impl Parser<'a, (), E> +where + ToError: Fn(Position) -> E, + E: 'a, +{ + debug_assert_ne!(word_1, b'\n'); + debug_assert_ne!(word_2, b'\n'); + debug_assert_ne!(word_3, b'\n'); + debug_assert_ne!(word_4, b'\n'); + debug_assert_ne!(word_5, b'\n'); + debug_assert_ne!(word_6, b'\n'); + debug_assert_ne!(word_7, b'\n'); + debug_assert_ne!(word_8, b'\n'); + debug_assert_ne!(word_9, b'\n'); + debug_assert_ne!(word_10, b'\n'); + + let needle = [ + word_1, word_2, word_3, word_4, word_5, word_6, word_7, word_8, word_9, word_10, + ]; + + move |_arena: &'a Bump, state: State<'a>, _min_indent: u32| { + if state.bytes().starts_with(&needle) { + let state = state.advance(10); + Ok((MadeProgress, (), state)) + } else { + Err((NoProgress, to_error(state.pos()))) + } + } +} + #[macro_export] macro_rules! word1_check_indent { ($word:expr, $word_problem:expr, $min_indent:expr, $indent_problem:expr) => { From b1d592ec377b6c7208cf92a6e1e544365d161aa5 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 07:15:30 -0400 Subject: [PATCH 02/55] has clause -> implements clause --- crates/compiler/builtins/roc/Bool.roc | 4 +- crates/compiler/builtins/roc/Decode.roc | 48 ++++++++--------- crates/compiler/builtins/roc/Dict.roc | 54 ++++++++++---------- crates/compiler/builtins/roc/Encode.roc | 50 +++++++++--------- crates/compiler/builtins/roc/Hash.roc | 30 +++++------ crates/compiler/builtins/roc/List.roc | 10 ++-- crates/compiler/builtins/roc/Set.roc | 30 +++++------ crates/compiler/parse/src/type_annotation.rs | 44 ++++++++++------ 8 files changed, 142 insertions(+), 128 deletions(-) diff --git a/crates/compiler/builtins/roc/Bool.roc b/crates/compiler/builtins/roc/Bool.roc index d16e8b24944..3b425e9bf19 100644 --- a/crates/compiler/builtins/roc/Bool.roc +++ b/crates/compiler/builtins/roc/Bool.roc @@ -30,7 +30,7 @@ Eq has ## for more detail. ## 5. Functions cannot be compared for structural equality, therefore Roc ## cannot derive `isEq` for types that contain functions. - isEq : a, a -> Bool | a has Eq + isEq : a, a -> Bool | a implements Eq ## Represents the boolean true and false using an opaque type. ## `Bool` implements the `Eq` ability. @@ -116,7 +116,7 @@ not : Bool -> Bool ## expect (Bool.false != Bool.false) == Bool.false ## expect "Apples" != "Oranges" ## ``` -isNotEq : a, a -> Bool | a has Eq +isNotEq : a, a -> Bool | a implements Eq isNotEq = \a, b -> structuralNotEq a b # INTERNAL COMPILER USE ONLY: used to lower calls to `isEq` to structural diff --git a/crates/compiler/builtins/roc/Decode.roc b/crates/compiler/builtins/roc/Decode.roc index 3f42aa6b624..850b71de30a 100644 --- a/crates/compiler/builtins/roc/Decode.roc +++ b/crates/compiler/builtins/roc/Decode.roc @@ -73,30 +73,30 @@ DecodeResult val : { result : Result val DecodeError, rest : List U8 } ## Decodes a `List U8` of utf-8 bytes where `val` is the type of the decoded ## value, and `fmt` is a [Decoder] which implements the [DecoderFormatting] ## ability -Decoder val fmt := List U8, fmt -> DecodeResult val | fmt has DecoderFormatting +Decoder val fmt := List U8, fmt -> DecodeResult val | fmt implements DecoderFormatting ## Definition of the [Decoding] ability Decoding has - decoder : Decoder val fmt | val has Decoding, fmt has DecoderFormatting + decoder : Decoder val fmt | val implements Decoding, fmt implements DecoderFormatting ## Definition of the [DecoderFormatting] ability DecoderFormatting has - u8 : Decoder U8 fmt | fmt has DecoderFormatting - u16 : Decoder U16 fmt | fmt has DecoderFormatting - u32 : Decoder U32 fmt | fmt has DecoderFormatting - u64 : Decoder U64 fmt | fmt has DecoderFormatting - u128 : Decoder U128 fmt | fmt has DecoderFormatting - i8 : Decoder I8 fmt | fmt has DecoderFormatting - i16 : Decoder I16 fmt | fmt has DecoderFormatting - i32 : Decoder I32 fmt | fmt has DecoderFormatting - i64 : Decoder I64 fmt | fmt has DecoderFormatting - i128 : Decoder I128 fmt | fmt has DecoderFormatting - f32 : Decoder F32 fmt | fmt has DecoderFormatting - f64 : Decoder F64 fmt | fmt has DecoderFormatting - dec : Decoder Dec fmt | fmt has DecoderFormatting - bool : Decoder Bool fmt | fmt has DecoderFormatting - string : Decoder Str fmt | fmt has DecoderFormatting - list : Decoder elem fmt -> Decoder (List elem) fmt | fmt has DecoderFormatting + u8 : Decoder U8 fmt | fmt implements DecoderFormatting + u16 : Decoder U16 fmt | fmt implements DecoderFormatting + u32 : Decoder U32 fmt | fmt implements DecoderFormatting + u64 : Decoder U64 fmt | fmt implements DecoderFormatting + u128 : Decoder U128 fmt | fmt implements DecoderFormatting + i8 : Decoder I8 fmt | fmt implements DecoderFormatting + i16 : Decoder I16 fmt | fmt implements DecoderFormatting + i32 : Decoder I32 fmt | fmt implements DecoderFormatting + i64 : Decoder I64 fmt | fmt implements DecoderFormatting + i128 : Decoder I128 fmt | fmt implements DecoderFormatting + f32 : Decoder F32 fmt | fmt implements DecoderFormatting + f64 : Decoder F64 fmt | fmt implements DecoderFormatting + dec : Decoder Dec fmt | fmt implements DecoderFormatting + bool : Decoder Bool fmt | fmt implements DecoderFormatting + string : Decoder Str fmt | fmt implements DecoderFormatting + list : Decoder elem fmt -> Decoder (List elem) fmt | fmt implements DecoderFormatting ## `record state stepField finalizer` decodes a record field-by-field. ## @@ -104,7 +104,7 @@ DecoderFormatting has ## `Skip` if the field is not a part of the decoded record. ## ## `finalizer` should produce the record value from the decoded `state`. - record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting + record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt implements DecoderFormatting ## `tuple state stepElem finalizer` decodes a tuple element-by-element. ## @@ -113,7 +113,7 @@ DecoderFormatting has ## index passed to `stepElem` is 0-indexed. ## ## `finalizer` should produce the tuple value from the decoded `state`. - tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting + tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt | fmt implements DecoderFormatting ## Build a custom [Decoder] function. For example the implementation of ## `decodeBool` could be defined as follows; @@ -125,11 +125,11 @@ DecoderFormatting has ## ['t', 'r', 'u', 'e', ..] -> { result: Ok Bool.true, rest: List.drop bytes 4 } ## _ -> { result: Err TooShort, rest: bytes } ## ``` -custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting +custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt implements DecoderFormatting custom = \decode -> @Decoder decode ## Decode a `List U8` utf-8 bytes using a specific [Decoder] function -decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt has DecoderFormatting +decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt implements DecoderFormatting decodeWith = \bytes, @Decoder decode, fmt -> decode bytes fmt ## Decode a `List U8` utf-8 bytes and return a [DecodeResult](#DecodeResult) @@ -141,7 +141,7 @@ decodeWith = \bytes, @Decoder decode, fmt -> decode bytes fmt ## ## actual.result == expected ## ``` -fromBytesPartial : List U8, fmt -> DecodeResult val | val has Decoding, fmt has DecoderFormatting +fromBytesPartial : List U8, fmt -> DecodeResult val | val implements Decoding, fmt implements DecoderFormatting fromBytesPartial = \bytes, fmt -> decodeWith bytes decoder fmt ## Decode a `List U8` utf-8 bytes and return a [Result] with no leftover bytes @@ -155,7 +155,7 @@ fromBytesPartial = \bytes, fmt -> decodeWith bytes decoder fmt ## ## actual == expected ## ``` -fromBytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError | val has Decoding, fmt has DecoderFormatting +fromBytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError | val implements Decoding, fmt implements DecoderFormatting fromBytes = \bytes, fmt -> when fromBytesPartial bytes fmt is { result, rest } -> diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 0db8f601cab..57d5091c800 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -97,13 +97,13 @@ Dict k v := { dataIndices : List Nat, data : List (T k v), size : Nat, -} | k has Hash & Eq +} | k implements Hash & Eq ## Return an empty dictionary. ## ``` ## emptyDict = Dict.empty {} ## ``` -empty : {} -> Dict k v | k has Hash & Eq +empty : {} -> Dict k v | k implements Hash & Eq empty = \{} -> @Dict { metadata: List.repeat emptySlot 8, @@ -120,7 +120,7 @@ empty = \{} -> ## ## capacityOfDict = Dict.capacity foodDict ## ``` -capacity : Dict k v -> Nat | k has Hash & Eq +capacity : Dict k v -> Nat | k implements Hash & Eq capacity = \@Dict { dataIndices } -> cap = List.len dataIndices @@ -129,7 +129,7 @@ capacity = \@Dict { dataIndices } -> ## Return a dictionary with space allocated for a number of entries. This ## may provide a performance optimisation if you know how many entries will be ## inserted. -withCapacity : Nat -> Dict k v | k has Hash & Eq +withCapacity : Nat -> Dict k v | k implements Hash & Eq withCapacity = \_ -> # TODO: power of 2 * 8 and actual implementation empty {} @@ -140,7 +140,7 @@ withCapacity = \_ -> ## Dict.single "A" "B" ## |> Bool.isEq (Dict.insert (Dict.empty {}) "A" "B") ## ``` -single : k, v -> Dict k v | k has Hash & Eq +single : k, v -> Dict k v | k implements Hash & Eq single = \k, v -> insert (empty {}) k v @@ -153,7 +153,7 @@ single = \k, v -> ## |> Dict.insert 4 "Four" ## |> Bool.isEq (Dict.fromList [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"]) ## ``` -fromList : List (T k v) -> Dict k v | k has Hash & Eq +fromList : List (T k v) -> Dict k v | k implements Hash & Eq fromList = \data -> # TODO: make this efficient. Should just set data and then set all indicies in the hashmap. List.walk data (empty {}) (\dict, T k v -> insert dict k v) @@ -168,7 +168,7 @@ fromList = \data -> ## |> Dict.len ## |> Bool.isEq 3 ## ``` -len : Dict k v -> Nat | k has Hash & Eq +len : Dict k v -> Nat | k implements Hash & Eq len = \@Dict { size } -> size @@ -184,7 +184,7 @@ len = \@Dict { size } -> ## ## expect Dict.len clearSongs == 0 ## ``` -clear : Dict k v -> Dict k v | k has Hash & Eq +clear : Dict k v -> Dict k v | k implements Hash & Eq clear = \@Dict { metadata, dataIndices, data } -> cap = List.len dataIndices @@ -212,7 +212,7 @@ clear = \@Dict { metadata, dataIndices, data } -> ## |> Dict.walk 0 (\count, _, qty -> count + qty) ## |> Bool.isEq 36 ## ``` -walk : Dict k v, state, (state, k, v -> state) -> state | k has Hash & Eq +walk : Dict k v, state, (state, k, v -> state) -> state | k implements Hash & Eq walk = \@Dict { data }, initialState, transform -> List.walk data initialState (\state, T k v -> transform state k v) @@ -244,7 +244,7 @@ walk = \@Dict { data }, initialState, transform -> ## ## expect someoneIsAnAdult == Bool.true ## ``` -walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k has Hash & Eq +walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k implements Hash & Eq walkUntil = \@Dict { data }, initialState, transform -> List.walkUntil data initialState (\state, T k v -> transform state k v) @@ -259,7 +259,7 @@ walkUntil = \@Dict { data }, initialState, transform -> ## expect Dict.get dictionary 1 == Ok "Apple" ## expect Dict.get dictionary 2000 == Err KeyNotFound ## ``` -get : Dict k v, k -> Result v [KeyNotFound] | k has Hash & Eq +get : Dict k v, k -> Result v [KeyNotFound] | k implements Hash & Eq get = \@Dict { metadata, dataIndices, data }, key -> hashKey = createLowLevelHasher {} @@ -287,7 +287,7 @@ get = \@Dict { metadata, dataIndices, data }, key -> ## |> Dict.contains 1234 ## |> Bool.isEq Bool.true ## ``` -contains : Dict k v, k -> Bool | k has Hash & Eq +contains : Dict k v, k -> Bool | k implements Hash & Eq contains = \@Dict { metadata, dataIndices, data }, key -> hashKey = createLowLevelHasher {} @@ -312,7 +312,7 @@ contains = \@Dict { metadata, dataIndices, data }, key -> ## |> Dict.get "Apples" ## |> Bool.isEq (Ok 12) ## ``` -insert : Dict k v, k, v -> Dict k v | k has Hash & Eq +insert : Dict k v, k, v -> Dict k v | k implements Hash & Eq insert = \@Dict { metadata, dataIndices, data, size }, key, value -> hashKey = createLowLevelHasher {} @@ -358,7 +358,7 @@ insert = \@Dict { metadata, dataIndices, data, size }, key, value -> ## |> Dict.len ## |> Bool.isEq 0 ## ``` -remove : Dict k v, k -> Dict k v | k has Hash & Eq +remove : Dict k v, k -> Dict k v | k implements Hash & Eq remove = \@Dict { metadata, dataIndices, data, size }, key -> # TODO: change this from swap remove to tombstone and test is performance is still good. hashKey = @@ -402,7 +402,7 @@ remove = \@Dict { metadata, dataIndices, data, size }, key -> ## expect Dict.update (Dict.single "a" Bool.false) "a" alterValue == Dict.single "a" Bool.true ## expect Dict.update (Dict.single "a" Bool.true) "a" alterValue == Dict.empty {} ## ``` -update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v | k has Hash & Eq +update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v | k implements Hash & Eq update = \dict, key, alter -> # TODO: look into optimizing by merging substeps and reducing lookups. possibleValue = @@ -425,7 +425,7 @@ update = \dict, key, alter -> ## |> Dict.toList ## |> Bool.isEq [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"] ## ``` -toList : Dict k v -> List (T k v) | k has Hash & Eq +toList : Dict k v -> List (T k v) | k implements Hash & Eq toList = \@Dict { data } -> data @@ -440,7 +440,7 @@ toList = \@Dict { data } -> ## |> Dict.keys ## |> Bool.isEq [1,2,3,4] ## ``` -keys : Dict k v -> List k | k has Hash & Eq +keys : Dict k v -> List k | k implements Hash & Eq keys = \@Dict { data } -> List.map data (\T k _ -> k) @@ -455,7 +455,7 @@ keys = \@Dict { data } -> ## |> Dict.values ## |> Bool.isEq ["One","Two","Three","Four"] ## ``` -values : Dict k v -> List v | k has Hash & Eq +values : Dict k v -> List v | k implements Hash & Eq values = \@Dict { data } -> List.map data (\T _ v -> v) @@ -483,7 +483,7 @@ values = \@Dict { data } -> ## expect ## Dict.insertAll first second == expected ## ``` -insertAll : Dict k v, Dict k v -> Dict k v | k has Hash & Eq +insertAll : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq insertAll = \xs, ys -> walk ys xs insert @@ -505,7 +505,7 @@ insertAll = \xs, ys -> ## ## expect Dict.keepShared first second == first ## ``` -keepShared : Dict k v, Dict k v -> Dict k v | k has Hash & Eq +keepShared : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq keepShared = \xs, ys -> walk xs @@ -537,11 +537,11 @@ keepShared = \xs, ys -> ## ## expect Dict.removeAll first second == expected ## ``` -removeAll : Dict k v, Dict k v -> Dict k v | k has Hash & Eq +removeAll : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq removeAll = \xs, ys -> walk ys xs (\state, k, _ -> remove state k) -swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k has Hash & Eq +swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k implements Hash & Eq swapAndUpdateDataIndex = \@Dict { metadata, dataIndices, data, size }, removedIndex, lastIndex -> (T key _) = listGetUnsafe data lastIndex hashKey = @@ -605,7 +605,7 @@ nextEmptyOrDeletedHelper = \metadata, probe, offset -> # TODO: investigate if this needs to be split into more specific helper functions. # There is a chance that returning specific sub-info like the value would be faster. -findIndexHelper : List I8, List Nat, List (T k v), I8, k, Probe, Nat -> Result Nat [NotFound] | k has Hash & Eq +findIndexHelper : List I8, List Nat, List (T k v), I8, k, Probe, Nat -> Result Nat [NotFound] | k implements Hash & Eq findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset -> # For finding a value, we must search past all deleted element tombstones. index = Num.addWrap (mul8 probe.slotIndex) offset @@ -637,7 +637,7 @@ findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset -> # This is how we grow the container. # If we aren't to the load factor yet, just ignore this. # The container must have an updated size including any elements about to be inserted. -maybeRehash : Dict k v -> Dict k v | k has Hash & Eq +maybeRehash : Dict k v -> Dict k v | k implements Hash & Eq maybeRehash = \@Dict { metadata, dataIndices, data, size } -> cap = List.len dataIndices maxLoadCap = @@ -650,7 +650,7 @@ maybeRehash = \@Dict { metadata, dataIndices, data, size } -> @Dict { metadata, dataIndices, data, size } # TODO: switch rehash to iterate data and eventually clear out tombstones as well. -rehash : Dict k v -> Dict k v | k has Hash & Eq +rehash : Dict k v -> Dict k v | k implements Hash & Eq rehash = \@Dict { metadata, dataIndices, data, size } -> newLen = 2 * List.len dataIndices newDict = @@ -663,7 +663,7 @@ rehash = \@Dict { metadata, dataIndices, data, size } -> rehashHelper newDict metadata dataIndices data 0 -rehashHelper : Dict k v, List I8, List Nat, List (T k v), Nat -> Dict k v | k has Hash & Eq +rehashHelper : Dict k v, List I8, List Nat, List (T k v), Nat -> Dict k v | k implements Hash & Eq rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> when List.get oldMetadata index is Ok md -> @@ -684,7 +684,7 @@ rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> # Walked entire list, complete now. dict -insertForRehash : Dict k v, k, Nat -> Dict k v | k has Hash & Eq +insertForRehash : Dict k v, k, Nat -> Dict k v | k implements Hash & Eq insertForRehash = \@Dict { metadata, dataIndices, data, size }, key, dataIndex -> hashKey = createLowLevelHasher {} diff --git a/crates/compiler/builtins/roc/Encode.roc b/crates/compiler/builtins/roc/Encode.roc index 2ac900e3e78..26ba2f77cc9 100644 --- a/crates/compiler/builtins/roc/Encode.roc +++ b/crates/compiler/builtins/roc/Encode.roc @@ -47,40 +47,40 @@ interface Encode Bool.{ Bool }, ] -Encoder fmt := List U8, fmt -> List U8 | fmt has EncoderFormatting +Encoder fmt := List U8, fmt -> List U8 | fmt implements EncoderFormatting Encoding has - toEncoder : val -> Encoder fmt | val has Encoding, fmt has EncoderFormatting + toEncoder : val -> Encoder fmt | val implements Encoding, fmt implements EncoderFormatting EncoderFormatting has - u8 : U8 -> Encoder fmt | fmt has EncoderFormatting - u16 : U16 -> Encoder fmt | fmt has EncoderFormatting - u32 : U32 -> Encoder fmt | fmt has EncoderFormatting - u64 : U64 -> Encoder fmt | fmt has EncoderFormatting - u128 : U128 -> Encoder fmt | fmt has EncoderFormatting - i8 : I8 -> Encoder fmt | fmt has EncoderFormatting - i16 : I16 -> Encoder fmt | fmt has EncoderFormatting - i32 : I32 -> Encoder fmt | fmt has EncoderFormatting - i64 : I64 -> Encoder fmt | fmt has EncoderFormatting - i128 : I128 -> Encoder fmt | fmt has EncoderFormatting - f32 : F32 -> Encoder fmt | fmt has EncoderFormatting - f64 : F64 -> Encoder fmt | fmt has EncoderFormatting - dec : Dec -> Encoder fmt | fmt has EncoderFormatting - bool : Bool -> Encoder fmt | fmt has EncoderFormatting - string : Str -> Encoder fmt | fmt has EncoderFormatting - list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting - record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt has EncoderFormatting - tuple : List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting - tag : Str, List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting + u8 : U8 -> Encoder fmt | fmt implements EncoderFormatting + u16 : U16 -> Encoder fmt | fmt implements EncoderFormatting + u32 : U32 -> Encoder fmt | fmt implements EncoderFormatting + u64 : U64 -> Encoder fmt | fmt implements EncoderFormatting + u128 : U128 -> Encoder fmt | fmt implements EncoderFormatting + i8 : I8 -> Encoder fmt | fmt implements EncoderFormatting + i16 : I16 -> Encoder fmt | fmt implements EncoderFormatting + i32 : I32 -> Encoder fmt | fmt implements EncoderFormatting + i64 : I64 -> Encoder fmt | fmt implements EncoderFormatting + i128 : I128 -> Encoder fmt | fmt implements EncoderFormatting + f32 : F32 -> Encoder fmt | fmt implements EncoderFormatting + f64 : F64 -> Encoder fmt | fmt implements EncoderFormatting + dec : Dec -> Encoder fmt | fmt implements EncoderFormatting + bool : Bool -> Encoder fmt | fmt implements EncoderFormatting + string : Str -> Encoder fmt | fmt implements EncoderFormatting + list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting + record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt implements EncoderFormatting + tuple : List (Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting + tag : Str, List (Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting -custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting +custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt implements EncoderFormatting custom = \encoder -> @Encoder encoder -appendWith : List U8, Encoder fmt, fmt -> List U8 | fmt has EncoderFormatting +appendWith : List U8, Encoder fmt, fmt -> List U8 | fmt implements EncoderFormatting appendWith = \lst, @Encoder doEncoding, fmt -> doEncoding lst fmt -append : List U8, val, fmt -> List U8 | val has Encoding, fmt has EncoderFormatting +append : List U8, val, fmt -> List U8 | val implements Encoding, fmt implements EncoderFormatting append = \lst, val, fmt -> appendWith lst (toEncoder val) fmt -toBytes : val, fmt -> List U8 | val has Encoding, fmt has EncoderFormatting +toBytes : val, fmt -> List U8 | val implements Encoding, fmt implements EncoderFormatting toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index caed5814c85..da6b9dda1c3 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -32,7 +32,7 @@ Hash has ## Hashes a value into a [Hasher]. ## Note that [hash] does not produce a hash value itself; the hasher must be ## [complete]d in order to extract the hash value. - hash : hasher, a -> hasher | a has Hash, hasher has Hasher + hash : hasher, a -> hasher | a implements Hash, hasher implements Hasher ## Describes a hashing algorithm that is fed bytes and produces an integer hash. ## @@ -41,26 +41,26 @@ Hash has ## cryptographically-secure hashing. Hasher has ## Adds a list of bytes to the hasher. - addBytes : a, List U8 -> a | a has Hasher + addBytes : a, List U8 -> a | a implements Hasher ## Adds a single U8 to the hasher. - addU8 : a, U8 -> a | a has Hasher + addU8 : a, U8 -> a | a implements Hasher ## Adds a single U16 to the hasher. - addU16 : a, U16 -> a | a has Hasher + addU16 : a, U16 -> a | a implements Hasher ## Adds a single U32 to the hasher. - addU32 : a, U32 -> a | a has Hasher + addU32 : a, U32 -> a | a implements Hasher ## Adds a single U64 to the hasher. - addU64 : a, U64 -> a | a has Hasher + addU64 : a, U64 -> a | a implements Hasher ## Adds a single U128 to the hasher. - addU128 : a, U128 -> a | a has Hasher + addU128 : a, U128 -> a | a implements Hasher ## Completes the hasher, extracting a hash value from its ## accumulated hash state. - complete : a -> U64 | a has Hasher + complete : a -> U64 | a implements Hasher ## Adds a string into a [Hasher] by hashing its UTF-8 bytes. hashStrBytes = \hasher, s -> @@ -72,33 +72,33 @@ hashList = \hasher, lst -> hash accumHasher elem ## Adds a single [Bool] to a hasher. -hashBool : a, Bool -> a | a has Hasher +hashBool : a, Bool -> a | a implements Hasher hashBool = \hasher, b -> asU8 = if b then 1 else 0 addU8 hasher asU8 ## Adds a single I8 to a hasher. -hashI8 : a, I8 -> a | a has Hasher +hashI8 : a, I8 -> a | a implements Hasher hashI8 = \hasher, n -> addU8 hasher (Num.toU8 n) ## Adds a single I16 to a hasher. -hashI16 : a, I16 -> a | a has Hasher +hashI16 : a, I16 -> a | a implements Hasher hashI16 = \hasher, n -> addU16 hasher (Num.toU16 n) ## Adds a single I32 to a hasher. -hashI32 : a, I32 -> a | a has Hasher +hashI32 : a, I32 -> a | a implements Hasher hashI32 = \hasher, n -> addU32 hasher (Num.toU32 n) ## Adds a single I64 to a hasher. -hashI64 : a, I64 -> a | a has Hasher +hashI64 : a, I64 -> a | a implements Hasher hashI64 = \hasher, n -> addU64 hasher (Num.toU64 n) ## Adds a single I128 to a hasher. -hashI128 : a, I128 -> a | a has Hasher +hashI128 : a, I128 -> a | a implements Hasher hashI128 = \hasher, n -> addU128 hasher (Num.toU128 n) ## Adds a single Nat to a hasher. -hashNat : a, Nat -> a | a has Hasher +hashNat : a, Nat -> a | a implements Hasher hashNat = \hasher, n -> isPlatform32bit = x : Nat diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index 9d132096141..299b3487603 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -362,7 +362,7 @@ join = \lists -> List.walk lists (List.withCapacity totalLength) (\state, list -> List.concat state list) -contains : List a, a -> Bool | a has Eq +contains : List a, a -> Bool | a implements Eq contains = \list, needle -> List.any list (\x -> x == needle) @@ -1036,7 +1036,7 @@ intersperse = \list, sep -> ## is considered to "start with" an empty list. ## ## If the first list is empty, this only returns `Bool.true` if the second list is empty. -startsWith : List elem, List elem -> Bool | elem has Eq +startsWith : List elem, List elem -> Bool | elem implements Eq startsWith = \list, prefix -> # TODO once we have seamless slices, verify that this wouldn't # have better performance with a function like List.compareSublists @@ -1048,7 +1048,7 @@ startsWith = \list, prefix -> ## is considered to "end with" an empty list. ## ## If the first list is empty, this only returns `Bool.true` if the second list is empty. -endsWith : List elem, List elem -> Bool | elem has Eq +endsWith : List elem, List elem -> Bool | elem implements Eq endsWith = \list, suffix -> # TODO once we have seamless slices, verify that this wouldn't # have better performance with a function like List.compareSublists @@ -1078,7 +1078,7 @@ split = \elements, userSplitIndex -> ## ``` ## List.splitFirst [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo], after: [Bar, Z, Baz] } ## ``` -splitFirst : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem has Eq +splitFirst : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem implements Eq splitFirst = \list, delimiter -> when List.findFirstIndex list (\elem -> elem == delimiter) is Ok index -> @@ -1094,7 +1094,7 @@ splitFirst = \list, delimiter -> ## ``` ## List.splitLast [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo, Z, Bar], after: [Baz] } ## ``` -splitLast : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem has Eq +splitLast : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem implements Eq splitLast = \list, delimiter -> when List.findLastIndex list (\elem -> elem == delimiter) is Ok index -> diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index ba6a09069be..c13570c8951 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -25,7 +25,7 @@ interface Set # We should have this line above the next has. # It causes the formatter to fail currently. -# | k has Hash & Eq +# | k implements Hash & Eq ## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) ## type which stores a collection of unique values, without any ordering Set k := Dict.Dict k {} @@ -35,7 +35,7 @@ Set k := Dict.Dict k {} }, ] -isEq : Set k, Set k -> Bool | k has Hash & Eq +isEq : Set k, Set k -> Bool | k implements Hash & Eq isEq = \xs, ys -> if len xs != len ys then Bool.false @@ -53,7 +53,7 @@ isEq = \xs, ys -> ## ## expect countValues == 0 ## ``` -empty : {} -> Set k | k has Hash & Eq +empty : {} -> Set k | k implements Hash & Eq empty = \{} -> @Set (Dict.empty {}) ## Creates a new `Set` with a single value. @@ -63,7 +63,7 @@ empty = \{} -> @Set (Dict.empty {}) ## ## expect countValues == 1 ## ``` -single : k -> Set k | k has Hash & Eq +single : k -> Set k | k implements Hash & Eq single = \key -> Dict.single key {} |> @Set @@ -79,7 +79,7 @@ single = \key -> ## ## expect countValues == 3 ## ``` -insert : Set k, k -> Set k | k has Hash & Eq +insert : Set k, k -> Set k | k implements Hash & Eq insert = \@Set dict, key -> Dict.insert dict key {} |> @Set @@ -112,7 +112,7 @@ expect ## ## expect countValues == 3 ## ``` -len : Set k -> Nat | k has Hash & Eq +len : Set k -> Nat | k implements Hash & Eq len = \@Set dict -> Dict.len dict @@ -142,7 +142,7 @@ expect ## expect has10 == Bool.false ## expect has20 == Bool.true ## ``` -remove : Set k, k -> Set k | k has Hash & Eq +remove : Set k, k -> Set k | k implements Hash & Eq remove = \@Set dict, key -> Dict.remove dict key |> @Set @@ -161,7 +161,7 @@ remove = \@Set dict, key -> ## expect hasApple == Bool.true ## expect hasBanana == Bool.false ## ``` -contains : Set k, k -> Bool | k has Hash & Eq +contains : Set k, k -> Bool | k implements Hash & Eq contains = \@Set dict, key -> Dict.contains dict key @@ -174,7 +174,7 @@ contains = \@Set dict, key -> ## ## expect Set.toList numbers == values ## ``` -toList : Set k -> List k | k has Hash & Eq +toList : Set k -> List k | k implements Hash & Eq toList = \@Set dict -> Dict.keys dict @@ -188,7 +188,7 @@ toList = \@Set dict -> ## ## expect Set.fromList [Pear, Apple, Banana] == values ## ``` -fromList : List k -> Set k | k has Hash & Eq +fromList : List k -> Set k | k implements Hash & Eq fromList = \list -> initial = @Set (Dict.withCapacity (List.len list)) @@ -204,7 +204,7 @@ fromList = \list -> ## ## expect Set.union set1 set2 == Set.fromList [Left, Right] ## ``` -union : Set k, Set k -> Set k | k has Hash & Eq +union : Set k, Set k -> Set k | k implements Hash & Eq union = \@Set dict1, @Set dict2 -> Dict.insertAll dict1 dict2 |> @Set @@ -217,7 +217,7 @@ union = \@Set dict1, @Set dict2 -> ## ## expect Set.intersection set1 set2 == Set.single Left ## ``` -intersection : Set k, Set k -> Set k | k has Hash & Eq +intersection : Set k, Set k -> Set k | k implements Hash & Eq intersection = \@Set dict1, @Set dict2 -> Dict.keepShared dict1 dict2 |> @Set @@ -231,7 +231,7 @@ intersection = \@Set dict1, @Set dict2 -> ## ## expect Set.difference first second == Set.fromList [Up, Down] ## ``` -difference : Set k, Set k -> Set k | k has Hash & Eq +difference : Set k, Set k -> Set k | k implements Hash & Eq difference = \@Set dict1, @Set dict2 -> Dict.removeAll dict1 dict2 |> @Set @@ -254,7 +254,7 @@ difference = \@Set dict1, @Set dict2 -> ## ## expect result == 2 ## ``` -walk : Set k, state, (state, k -> state) -> state | k has Hash & Eq +walk : Set k, state, (state, k -> state) -> state | k implements Hash & Eq walk = \@Set dict, state, step -> Dict.walk dict state (\s, k, _ -> step s k) @@ -273,7 +273,7 @@ walk = \@Set dict, state, step -> ## ## expect result == FoundTheAnswer ## ``` -walkUntil : Set k, state, (state, k -> [Continue state, Break state]) -> state | k has Hash & Eq +walkUntil : Set k, state, (state, k -> [Continue state, Break state]) -> state | k implements Hash & Eq walkUntil = \@Set dict, state, step -> Dict.walkUntil dict state (\s, k, _ -> step s k) diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index e2fe0e78d51..c244996f5ec 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -12,8 +12,8 @@ use crate::parser::{ absolute_column_min_indent, increment_min_indent, then, ERecord, ETypeAbilityImpl, }; use crate::parser::{ - allocated, backtrackable, fail, optional, specialize, specialize_ref, word1, word2, word3, - EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser, + allocated, backtrackable, fail, optional, specialize, specialize_ref, word1, word10, word2, + word3, EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser, Progress::{self, *}, }; use crate::state::State; @@ -444,9 +444,9 @@ fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc>>, ETyp ) } -fn has_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { +fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { map!( - // Suppose we are trying to parse "a has Hash" + // Suppose we are trying to parse "a implements Hash" and!( space0_around_ee( // Parse "a", with appropriate spaces @@ -458,8 +458,20 @@ fn has_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { EType::TIndentEnd ), skip_first!( - // Parse "has"; we don't care about this keyword - word3(b'h', b'a', b's', EType::THasClause), + // Parse "implements"; we don't care about this keyword + word10( + b'i', + b'm', + b'p', + b'l', + b'e', + b'm', + b'e', + b'n', + b't', + b's', + EType::THasClause + ), // Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash" absolute_column_min_indent(ability_chain()) ) @@ -470,18 +482,18 @@ fn has_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { &abilities.last().unwrap().region, ); let region = Region::span_across(&var.region, &abilities_region); - let has_clause = HasClause { + let implements_clause = HasClause { var, abilities: abilities.into_bump_slice(), }; - Loc::at(region, has_clause) + Loc::at(region, implements_clause) } ) } -/// Parse a chain of `has` clauses, e.g. " | a has Hash, b has Eq". +/// Parse a chain of `implements` clauses, e.g. " | a implements Hash, b implements Eq". /// Returns the clauses and spaces before the starting "|", if there were any. -fn has_clause_chain<'a>( +fn implements_clause_chain<'a>( ) -> impl Parser<'a, (&'a [CommentOrNewline<'a>], &'a [Loc>]), EType<'a>> { move |arena, state: State<'a>, min_indent: u32| { let (_, (spaces_before, ()), state) = @@ -489,11 +501,13 @@ fn has_clause_chain<'a>( .parse(arena, state, min_indent)?; // Parse the first clause (there must be one), then the rest - let (_, first_clause, state) = has_clause().parse(arena, state, min_indent)?; + let (_, first_clause, state) = implements_clause().parse(arena, state, min_indent)?; - let (_, mut clauses, state) = - zero_or_more!(skip_first!(word1(b',', EType::THasClause), has_clause())) - .parse(arena, state, min_indent)?; + let (_, mut clauses, state) = zero_or_more!(skip_first!( + word1(b',', EType::THasClause), + implements_clause() + )) + .parse(arena, state, min_indent)?; // Usually the number of clauses shouldn't be too large, so this is okay clauses.insert(0, first_clause); @@ -642,7 +656,7 @@ fn expression<'a>( // Finally, try to parse a where clause if there is one. // The where clause must be at least as deep as where the type annotation started. - match has_clause_chain().parse(arena, state.clone(), min_indent) { + match implements_clause_chain().parse(arena, state.clone(), min_indent) { Ok((where_progress, (spaces_before, has_chain), state)) => { let region = Region::span_across(&annot.region, &has_chain.last().unwrap().region); let type_annot = if !spaces_before.is_empty() { From d2fed03cb1816ceeb134b354f5ff93aedcba7bd2 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 08:04:26 -0400 Subject: [PATCH 03/55] has [abilities] -> implements [abilities] --- crates/compiler/parse/src/type_annotation.rs | 26 ++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index c244996f5ec..0c587fb9c96 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -13,7 +13,7 @@ use crate::parser::{ }; use crate::parser::{ allocated, backtrackable, fail, optional, specialize, specialize_ref, word1, word10, word2, - word3, EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser, + EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser, Progress::{self, *}, }; use crate::state::State; @@ -520,17 +520,29 @@ fn implements_clause_chain<'a>( } } -/// Parse a has-abilities clause, e.g. `has [Eq, Hash]`. -pub fn has_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { +/// Parse a implements-abilities clause, e.g. `implements [Eq, Hash]`. +pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { increment_min_indent(skip_first!( - // Parse "has"; we don't care about this keyword - word3(b'h', b'a', b's', EType::THasClause), + // Parse "implements"; we don't care about this keyword + word10( + b'i', + b'm', + b'p', + b'l', + b'e', + b'm', + b'e', + b'n', + b't', + b's', + EType::THasClause + ), // Parse "Hash"; this may be qualified from another module like "Hash.Hash" space0_before_e( loc!(map!( collection_trailing_sep_e!( word1(b'[', EType::TStart), - loc!(parse_has_ability()), + loc!(parse_implements_ability()), word1(b',', EType::TEnd), word1(b']', EType::TEnd), HasAbility::SpaceBefore @@ -542,7 +554,7 @@ pub fn has_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> )) } -fn parse_has_ability<'a>() -> impl Parser<'a, HasAbility<'a>, EType<'a>> { +fn parse_implements_ability<'a>() -> impl Parser<'a, HasAbility<'a>, EType<'a>> { increment_min_indent(record!(HasAbility::HasAbility { ability: loc!(specialize(EType::TApply, concrete_type())), impls: optional(backtrackable(space0_before_e( From 64c34a5c6d3404986a2f1b91d75ce7c71a7ad11c Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 08:12:20 -0400 Subject: [PATCH 04/55] ast::Has -> ast::Implements --- crates/compiler/fmt/src/spaces.rs | 10 +++++----- crates/compiler/parse/src/ast.rs | 24 ++++++++++++------------ crates/compiler/parse/src/expr.rs | 13 +++++++------ crates/compiler/parse/src/pattern.rs | 10 +++++++--- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 5408814c096..eba9b22e6c2 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -3,9 +3,9 @@ use bumpalo::Bump; use roc_module::called_via::{BinOp, UnaryOp}; use roc_parse::{ ast::{ - AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, Has, HasAbilities, - HasAbility, HasClause, HasImpls, Header, Module, Pattern, RecordBuilderField, Spaced, - Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef, + AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, HasAbilities, + HasAbility, HasClause, HasImpls, Header, Implements, Module, Pattern, RecordBuilderField, + Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef, WhenBranch, }, header::{ @@ -569,9 +569,9 @@ impl<'a> RemoveSpaces<'a> for ValueDef<'a> { } } -impl<'a> RemoveSpaces<'a> for Has<'a> { +impl<'a> RemoveSpaces<'a> for Implements<'a> { fn remove_spaces(&self, _arena: &'a Bump) -> Self { - Has::Has + Implements::Implements } } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index c0d35d67c0e..424f8bc9d75 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -357,12 +357,12 @@ impl<'a> TypeHeader<'a> { } } -/// The `has` keyword associated with ability definitions. +/// The `implements` keyword associated with ability definitions. #[derive(Debug, Clone, Copy, PartialEq)] -pub enum Has<'a> { - Has, - SpaceBefore(&'a Has<'a>, &'a [CommentOrNewline<'a>]), - SpaceAfter(&'a Has<'a>, &'a [CommentOrNewline<'a>]), +pub enum Implements<'a> { + Implements, + SpaceBefore(&'a Implements<'a>, &'a [CommentOrNewline<'a>]), + SpaceAfter(&'a Implements<'a>, &'a [CommentOrNewline<'a>]), } /// An ability demand is a value defining the ability; for example `hash : a -> U64 | a has Hash` @@ -402,7 +402,7 @@ pub enum TypeDef<'a> { /// hash : a -> U64 | a has Hash Ability { header: TypeHeader<'a>, - loc_has: Loc>, + loc_has: Loc>, members: &'a [AbilityMember<'a>], }, } @@ -1245,12 +1245,12 @@ impl<'a> Spaceable<'a> for Tag<'a> { } } -impl<'a> Spaceable<'a> for Has<'a> { +impl<'a> Spaceable<'a> for Implements<'a> { fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - Has::SpaceBefore(self, spaces) + Implements::SpaceBefore(self, spaces) } fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - Has::SpaceAfter(self, spaces) + Implements::SpaceAfter(self, spaces) } } @@ -1698,11 +1698,11 @@ impl<'a> Malformed for AbilityMember<'a> { } } -impl<'a> Malformed for Has<'a> { +impl<'a> Malformed for Implements<'a> { fn is_malformed(&self) -> bool { match self { - Has::Has => false, - Has::SpaceBefore(has, _) | Has::SpaceAfter(has, _) => has.is_malformed(), + Implements::Implements => false, + Implements::SpaceBefore(has, _) | Implements::SpaceAfter(has, _) => has.is_malformed(), } } } diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index e77bd8a216c..62a2159050f 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1,6 +1,7 @@ use crate::ast::{ - AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces, Has, HasAbilities, - Pattern, RecordBuilderField, Spaceable, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef, + AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces, HasAbilities, + Implements, Pattern, RecordBuilderField, Spaceable, Spaces, TypeAnnotation, TypeDef, + TypeHeader, ValueDef, }; use crate::blankspace::{ space0_after_e, space0_around_e_no_after_indent_check, space0_around_ee, space0_before_e, @@ -1075,7 +1076,7 @@ fn opaque_signature_with_space_before<'a>( ), optional(backtrackable(specialize( EExpr::Type, - space0_before_e(type_annotation::has_abilities(), EType::TIndentStart,), + space0_before_e(type_annotation::implements_abilities(), EType::TIndentStart,), ))) ) } @@ -1363,7 +1364,7 @@ fn finish_parsing_ability_def_help<'a>( start_column: u32, name: Loc<&'a str>, args: &'a [Loc>], - loc_has: Loc>, + loc_has: Loc>, arena: &'a Bump, state: State<'a>, ) -> ParseResult<'a, (TypeDef<'a>, Region), EExpr<'a>> { @@ -1664,10 +1665,10 @@ fn parse_expr_end<'a>( // Attach any spaces to the `has` keyword let has = if !expr_state.spaces_after.is_empty() { arena - .alloc(Has::Has) + .alloc(Implements::Implements) .with_spaces_before(expr_state.spaces_after, has.region) } else { - Loc::at(has.region, Has::Has) + Loc::at(has.region, Implements::Implements) }; let args = arguments.into_bump_slice(); diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 0854eb04be0..b35dac7e5d1 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -1,4 +1,4 @@ -use crate::ast::{Has, Pattern, PatternAs, Spaceable}; +use crate::ast::{Implements, Pattern, PatternAs, Spaceable}; use crate::blankspace::{space0_e, spaces, spaces_before}; use crate::ident::{lowercase_ident, parse_ident, Accessor, Ident}; use crate::keyword; @@ -154,12 +154,16 @@ fn loc_tag_pattern_arg<'a>( } } -pub fn loc_has_parser<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { +pub fn loc_has_parser<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { then( loc_tag_pattern_arg(false), |_arena, state, progress, pattern| { if matches!(pattern.value, Pattern::Identifier("has")) { - Ok((progress, Loc::at(pattern.region, Has::Has), state)) + Ok(( + progress, + Loc::at(pattern.region, Implements::Implements), + state, + )) } else { Err((progress, EPattern::End(state.pos()))) } From ebbdae6c284110c0e9c1ab21d1da4ab48c5938a5 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 08:20:44 -0400 Subject: [PATCH 05/55] ast::HasClause -> ast::ImplementsClause --- crates/compiler/can/src/annotation.rs | 4 ++-- crates/compiler/fmt/src/annotation.rs | 6 +++--- crates/compiler/fmt/src/spaces.rs | 10 +++++----- crates/compiler/load_internal/src/docs.rs | 2 +- crates/compiler/parse/src/ast.rs | 6 +++--- crates/compiler/parse/src/type_annotation.rs | 10 +++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/compiler/can/src/annotation.rs b/crates/compiler/can/src/annotation.rs index e80033c1e33..85d4501cf16 100644 --- a/crates/compiler/can/src/annotation.rs +++ b/crates/compiler/can/src/annotation.rs @@ -1064,13 +1064,13 @@ fn canonicalize_has_clause( scope: &mut Scope, var_store: &mut VarStore, introduced_variables: &mut IntroducedVariables, - clause: &Loc>, + clause: &Loc>, pending_abilities_in_scope: &PendingAbilitiesInScope, references: &mut VecSet, ) -> Result<(), Type> { let Loc { region, - value: roc_parse::ast::HasClause { var, abilities }, + value: roc_parse::ast::ImplementsClause { var, abilities }, } = clause; let region = *region; diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 8f7614af346..d2a6142b33e 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -4,8 +4,8 @@ use crate::{ Buf, }; use roc_parse::ast::{ - AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, HasAbility, HasClause, HasImpls, - RecordBuilderField, Tag, TypeAnnotation, TypeHeader, + AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, HasAbility, HasImpls, + ImplementsClause, RecordBuilderField, Tag, TypeAnnotation, TypeHeader, }; use roc_parse::ident::UppercaseIdent; use roc_region::all::Loc; @@ -645,7 +645,7 @@ impl<'a> Formattable for Tag<'a> { } } -impl<'a> Formattable for HasClause<'a> { +impl<'a> Formattable for ImplementsClause<'a> { fn is_multiline(&self) -> bool { // No, always put abilities in a "has" clause on one line false diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index eba9b22e6c2..35cfce7fa34 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -4,9 +4,9 @@ use roc_module::called_via::{BinOp, UnaryOp}; use roc_parse::{ ast::{ AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, HasAbilities, - HasAbility, HasClause, HasImpls, Header, Implements, Module, Pattern, RecordBuilderField, - Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef, - WhenBranch, + HasAbility, HasImpls, Header, Implements, ImplementsClause, Module, Pattern, + RecordBuilderField, Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, + TypeHeader, ValueDef, WhenBranch, }, header::{ AppHeader, ExposedName, HostedHeader, ImportsEntry, InterfaceHeader, KeywordItem, @@ -862,9 +862,9 @@ impl<'a> RemoveSpaces<'a> for TypeAnnotation<'a> { } } -impl<'a> RemoveSpaces<'a> for HasClause<'a> { +impl<'a> RemoveSpaces<'a> for ImplementsClause<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { - HasClause { + ImplementsClause { var: self.var.remove_spaces(arena), abilities: self.abilities.remove_spaces(arena), } diff --git a/crates/compiler/load_internal/src/docs.rs b/crates/compiler/load_internal/src/docs.rs index 27dee8c8a02..f74667f9360 100644 --- a/crates/compiler/load_internal/src/docs.rs +++ b/crates/compiler/load_internal/src/docs.rs @@ -553,7 +553,7 @@ fn ability_member_type_to_docs( let has_clauses = has_clauses .iter() .map(|hc| { - let ast::HasClause { var, abilities } = hc.value; + let ast::ImplementsClause { var, abilities } = hc.value; ( var.value.extract_spaces().item.to_string(), abilities diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 424f8bc9d75..c6084e6b537 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -538,7 +538,7 @@ impl<'a> Defs<'a> { pub type AbilityName<'a> = Loc>; #[derive(Debug, Copy, Clone, PartialEq)] -pub struct HasClause<'a> { +pub struct ImplementsClause<'a> { pub var: Loc>, pub abilities: &'a [AbilityName<'a>], } @@ -642,7 +642,7 @@ pub enum TypeAnnotation<'a> { Wildcard, /// A "where" clause demanding abilities designated by a `|`, e.g. `a -> U64 | a has Hash` - Where(&'a Loc>, &'a [Loc>]), + Where(&'a Loc>, &'a [Loc>]), // We preserve this for the formatter; canonicalization ignores it. SpaceBefore(&'a TypeAnnotation<'a>, &'a [CommentOrNewline<'a>]), @@ -1823,7 +1823,7 @@ impl<'a> Malformed for Tag<'a> { } } -impl<'a> Malformed for HasClause<'a> { +impl<'a> Malformed for ImplementsClause<'a> { fn is_malformed(&self) -> bool { self.abilities.iter().any(|ability| ability.is_malformed()) } diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 0c587fb9c96..26cc88da8d6 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -1,6 +1,6 @@ use crate::ast::{ - AssignedField, CommentOrNewline, Expr, HasAbilities, HasAbility, HasClause, HasImpls, Pattern, - Spaceable, Spaced, Tag, TypeAnnotation, TypeHeader, + AssignedField, CommentOrNewline, Expr, HasAbilities, HasAbility, HasImpls, ImplementsClause, + Pattern, Spaceable, Spaced, Tag, TypeAnnotation, TypeHeader, }; use crate::blankspace::{ space0_around_ee, space0_before_e, space0_before_optional_after, space0_e, @@ -444,7 +444,7 @@ fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc>>, ETyp ) } -fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { +fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { map!( // Suppose we are trying to parse "a implements Hash" and!( @@ -482,7 +482,7 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { &abilities.last().unwrap().region, ); let region = Region::span_across(&var.region, &abilities_region); - let implements_clause = HasClause { + let implements_clause = ImplementsClause { var, abilities: abilities.into_bump_slice(), }; @@ -494,7 +494,7 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<'a>> { /// Parse a chain of `implements` clauses, e.g. " | a implements Hash, b implements Eq". /// Returns the clauses and spaces before the starting "|", if there were any. fn implements_clause_chain<'a>( -) -> impl Parser<'a, (&'a [CommentOrNewline<'a>], &'a [Loc>]), EType<'a>> { +) -> impl Parser<'a, (&'a [CommentOrNewline<'a>], &'a [Loc>]), EType<'a>> { move |arena, state: State<'a>, min_indent: u32| { let (_, (spaces_before, ()), state) = and!(space0_e(EType::TIndentStart), word1(b'|', EType::TWhereBar)) From 413ccb24ad27714a57511777a80c0b8388b98b06 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 08:24:02 -0400 Subject: [PATCH 06/55] ast::HasImpls -> ast::AbilityImpls --- crates/compiler/fmt/src/annotation.rs | 14 +++--- crates/compiler/fmt/src/spaces.rs | 12 +++-- crates/compiler/parse/src/ast.rs | 48 ++++++++++---------- crates/compiler/parse/src/type_annotation.rs | 6 +-- 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index d2a6142b33e..762d2bb1f44 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -4,7 +4,7 @@ use crate::{ Buf, }; use roc_parse::ast::{ - AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, HasAbility, HasImpls, + AbilityImpls, AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, HasAbility, ImplementsClause, RecordBuilderField, Tag, TypeAnnotation, TypeHeader, }; use roc_parse::ident::UppercaseIdent; @@ -668,30 +668,30 @@ impl<'a> Formattable for ImplementsClause<'a> { } } -impl<'a> Formattable for HasImpls<'a> { +impl<'a> Formattable for AbilityImpls<'a> { fn is_multiline(&self) -> bool { match self { - HasImpls::SpaceBefore(_, _) | HasImpls::SpaceAfter(_, _) => true, - HasImpls::HasImpls(impls) => is_collection_multiline(impls), + AbilityImpls::SpaceBefore(_, _) | AbilityImpls::SpaceAfter(_, _) => true, + AbilityImpls::AbilityImpls(impls) => is_collection_multiline(impls), } } fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) { match self { - HasImpls::HasImpls(impls) => { + AbilityImpls::AbilityImpls(impls) => { if newlines == Newlines::Yes { buf.newline(); buf.indent(indent); } fmt_collection(buf, indent, Braces::Curly, *impls, Newlines::No); } - HasImpls::SpaceBefore(impls, spaces) => { + AbilityImpls::SpaceBefore(impls, spaces) => { buf.newline(); buf.indent(indent); fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent); impls.format_with_options(buf, parens, Newlines::No, indent); } - HasImpls::SpaceAfter(impls, spaces) => { + AbilityImpls::SpaceAfter(impls, spaces) => { impls.format_with_options(buf, parens, newlines, indent); fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent); } diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 35cfce7fa34..f4516dbe821 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -3,8 +3,8 @@ use bumpalo::Bump; use roc_module::called_via::{BinOp, UnaryOp}; use roc_parse::{ ast::{ - AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, HasAbilities, - HasAbility, HasImpls, Header, Implements, ImplementsClause, Module, Pattern, + AbilityImpls, AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, + HasAbilities, HasAbility, Header, Implements, ImplementsClause, Module, Pattern, RecordBuilderField, Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef, WhenBranch, }, @@ -885,11 +885,13 @@ impl<'a> RemoveSpaces<'a> for Tag<'a> { } } -impl<'a> RemoveSpaces<'a> for HasImpls<'a> { +impl<'a> RemoveSpaces<'a> for AbilityImpls<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { match *self { - HasImpls::HasImpls(impls) => HasImpls::HasImpls(impls.remove_spaces(arena)), - HasImpls::SpaceBefore(has, _) | HasImpls::SpaceAfter(has, _) => { + AbilityImpls::AbilityImpls(impls) => { + AbilityImpls::AbilityImpls(impls.remove_spaces(arena)) + } + AbilityImpls::SpaceBefore(has, _) | AbilityImpls::SpaceAfter(has, _) => { has.remove_spaces(arena) } } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index c6084e6b537..7fab0f0150f 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -544,13 +544,13 @@ pub struct ImplementsClause<'a> { } #[derive(Debug, Copy, Clone, PartialEq)] -pub enum HasImpls<'a> { +pub enum AbilityImpls<'a> { // `{ eq: myEq }` - HasImpls(Collection<'a, Loc>>>), + AbilityImpls(Collection<'a, Loc>>>), // We preserve this for the formatter; canonicalization ignores it. - SpaceBefore(&'a HasImpls<'a>, &'a [CommentOrNewline<'a>]), - SpaceAfter(&'a HasImpls<'a>, &'a [CommentOrNewline<'a>]), + SpaceBefore(&'a AbilityImpls<'a>, &'a [CommentOrNewline<'a>]), + SpaceAfter(&'a AbilityImpls<'a>, &'a [CommentOrNewline<'a>]), } /// `Eq` or `Eq { eq: myEq }` @@ -559,7 +559,7 @@ pub enum HasAbility<'a> { HasAbility { /// Should be a zero-argument `Apply` or an error; we'll check this in canonicalization ability: Loc>, - impls: Option>>, + impls: Option>>, }, // We preserve this for the formatter; canonicalization ignores it. @@ -1254,12 +1254,12 @@ impl<'a> Spaceable<'a> for Implements<'a> { } } -impl<'a> Spaceable<'a> for HasImpls<'a> { +impl<'a> Spaceable<'a> for AbilityImpls<'a> { fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - HasImpls::SpaceBefore(self, spaces) + AbilityImpls::SpaceBefore(self, spaces) } fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - HasImpls::SpaceAfter(self, spaces) + AbilityImpls::SpaceAfter(self, spaces) } } @@ -1422,43 +1422,43 @@ impl<'a, T: Copy> ExtractSpaces<'a> for Spaced<'a, T> { } } -impl<'a> ExtractSpaces<'a> for HasImpls<'a> { +impl<'a> ExtractSpaces<'a> for AbilityImpls<'a> { type Item = Collection<'a, Loc>>>; fn extract_spaces(&self) -> Spaces<'a, Self::Item> { match self { - HasImpls::HasImpls(inner) => Spaces { + AbilityImpls::AbilityImpls(inner) => Spaces { before: &[], item: *inner, after: &[], }, - HasImpls::SpaceBefore(item, before) => match item { - HasImpls::HasImpls(inner) => Spaces { + AbilityImpls::SpaceBefore(item, before) => match item { + AbilityImpls::AbilityImpls(inner) => Spaces { before, item: *inner, after: &[], }, - HasImpls::SpaceBefore(_, _) => todo!(), - HasImpls::SpaceAfter(HasImpls::HasImpls(inner), after) => Spaces { + AbilityImpls::SpaceBefore(_, _) => todo!(), + AbilityImpls::SpaceAfter(AbilityImpls::AbilityImpls(inner), after) => Spaces { before, item: *inner, after, }, - HasImpls::SpaceAfter(_, _) => todo!(), + AbilityImpls::SpaceAfter(_, _) => todo!(), }, - HasImpls::SpaceAfter(item, after) => match item { - HasImpls::HasImpls(inner) => Spaces { + AbilityImpls::SpaceAfter(item, after) => match item { + AbilityImpls::AbilityImpls(inner) => Spaces { before: &[], item: *inner, after, }, - HasImpls::SpaceBefore(HasImpls::HasImpls(inner), before) => Spaces { + AbilityImpls::SpaceBefore(AbilityImpls::AbilityImpls(inner), before) => Spaces { before, item: *inner, after, }, - HasImpls::SpaceBefore(_, _) => todo!(), - HasImpls::SpaceAfter(_, _) => todo!(), + AbilityImpls::SpaceBefore(_, _) => todo!(), + AbilityImpls::SpaceAfter(_, _) => todo!(), }, } } @@ -1729,11 +1729,13 @@ impl<'a> Malformed for HasAbilities<'a> { } } -impl<'a> Malformed for HasImpls<'a> { +impl<'a> Malformed for AbilityImpls<'a> { fn is_malformed(&self) -> bool { match self { - HasImpls::HasImpls(impls) => impls.iter().any(|ability| ability.is_malformed()), - HasImpls::SpaceBefore(has, _) | HasImpls::SpaceAfter(has, _) => has.is_malformed(), + AbilityImpls::AbilityImpls(impls) => impls.iter().any(|ability| ability.is_malformed()), + AbilityImpls::SpaceBefore(has, _) | AbilityImpls::SpaceAfter(has, _) => { + has.is_malformed() + } } } } diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 26cc88da8d6..43fb96c3571 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -1,6 +1,6 @@ use crate::ast::{ - AssignedField, CommentOrNewline, Expr, HasAbilities, HasAbility, HasImpls, ImplementsClause, - Pattern, Spaceable, Spaced, Tag, TypeAnnotation, TypeHeader, + AbilityImpls, AssignedField, CommentOrNewline, Expr, HasAbilities, HasAbility, + ImplementsClause, Pattern, Spaceable, Spaced, Tag, TypeAnnotation, TypeHeader, }; use crate::blankspace::{ space0_around_ee, space0_before_e, space0_before_optional_after, space0_e, @@ -569,7 +569,7 @@ fn parse_implements_ability<'a>() -> impl Parser<'a, HasAbility<'a>, EType<'a>> AssignedField::SpaceBefore ) ), - HasImpls::HasImpls + AbilityImpls::AbilityImpls )), EType::TIndentEnd ))) From 9eb2180a0f4e0dabdd89d5318408e8f565bd7563 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 08:27:42 -0400 Subject: [PATCH 07/55] ast::HasAbility -> ast::ImplementsAbility --- crates/compiler/can/src/def.rs | 2 +- crates/compiler/fmt/src/annotation.rs | 14 +++++----- crates/compiler/fmt/src/spaces.rs | 16 ++++++----- crates/compiler/parse/src/ast.rs | 28 +++++++++++--------- crates/compiler/parse/src/type_annotation.rs | 8 +++--- 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 79c05a58716..14bd8086c9d 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -695,7 +695,7 @@ fn canonicalize_opaque<'a>( for has_ability in has_abilities.items { let region = has_ability.region; let (ability, opt_impls) = match has_ability.value.extract_spaces().item { - ast::HasAbility::HasAbility { ability, impls } => (ability, impls), + ast::ImplementsAbility::ImplementsAbility { ability, impls } => (ability, impls), _ => internal_error!("spaces not extracted"), }; diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 762d2bb1f44..f66ede894d5 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -4,7 +4,7 @@ use crate::{ Buf, }; use roc_parse::ast::{ - AbilityImpls, AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, HasAbility, + AbilityImpls, AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, ImplementsAbility, ImplementsClause, RecordBuilderField, Tag, TypeAnnotation, TypeHeader, }; use roc_parse::ident::UppercaseIdent; @@ -699,11 +699,11 @@ impl<'a> Formattable for AbilityImpls<'a> { } } -impl<'a> Formattable for HasAbility<'a> { +impl<'a> Formattable for ImplementsAbility<'a> { fn is_multiline(&self) -> bool { match self { - HasAbility::SpaceAfter(..) | HasAbility::SpaceBefore(..) => true, - HasAbility::HasAbility { ability, impls } => { + ImplementsAbility::SpaceAfter(..) | ImplementsAbility::SpaceBefore(..) => true, + ImplementsAbility::ImplementsAbility { ability, impls } => { ability.is_multiline() || impls.map(|i| i.is_multiline()).unwrap_or(false) } } @@ -711,7 +711,7 @@ impl<'a> Formattable for HasAbility<'a> { fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) { match self { - HasAbility::HasAbility { ability, impls } => { + ImplementsAbility::ImplementsAbility { ability, impls } => { if newlines == Newlines::Yes { buf.newline(); buf.indent(indent); @@ -722,13 +722,13 @@ impl<'a> Formattable for HasAbility<'a> { impls.format_with_options(buf, parens, newlines, indent); } } - HasAbility::SpaceBefore(ab, spaces) => { + ImplementsAbility::SpaceBefore(ab, spaces) => { buf.newline(); buf.indent(indent); fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent); ab.format_with_options(buf, parens, Newlines::No, indent) } - HasAbility::SpaceAfter(ab, spaces) => { + ImplementsAbility::SpaceAfter(ab, spaces) => { ab.format_with_options(buf, parens, newlines, indent); fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent); } diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index f4516dbe821..ed2d79adc42 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -4,7 +4,7 @@ use roc_module::called_via::{BinOp, UnaryOp}; use roc_parse::{ ast::{ AbilityImpls, AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, - HasAbilities, HasAbility, Header, Implements, ImplementsClause, Module, Pattern, + HasAbilities, Header, Implements, ImplementsAbility, ImplementsClause, Module, Pattern, RecordBuilderField, Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef, WhenBranch, }, @@ -898,14 +898,16 @@ impl<'a> RemoveSpaces<'a> for AbilityImpls<'a> { } } -impl<'a> RemoveSpaces<'a> for HasAbility<'a> { +impl<'a> RemoveSpaces<'a> for ImplementsAbility<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { match *self { - HasAbility::HasAbility { ability, impls } => HasAbility::HasAbility { - ability: ability.remove_spaces(arena), - impls: impls.remove_spaces(arena), - }, - HasAbility::SpaceBefore(has, _) | HasAbility::SpaceAfter(has, _) => { + ImplementsAbility::ImplementsAbility { ability, impls } => { + ImplementsAbility::ImplementsAbility { + ability: ability.remove_spaces(arena), + impls: impls.remove_spaces(arena), + } + } + ImplementsAbility::SpaceBefore(has, _) | ImplementsAbility::SpaceAfter(has, _) => { has.remove_spaces(arena) } } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 7fab0f0150f..b995297a465 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -555,22 +555,22 @@ pub enum AbilityImpls<'a> { /// `Eq` or `Eq { eq: myEq }` #[derive(Debug, Copy, Clone, PartialEq)] -pub enum HasAbility<'a> { - HasAbility { +pub enum ImplementsAbility<'a> { + ImplementsAbility { /// Should be a zero-argument `Apply` or an error; we'll check this in canonicalization ability: Loc>, impls: Option>>, }, // We preserve this for the formatter; canonicalization ignores it. - SpaceBefore(&'a HasAbility<'a>, &'a [CommentOrNewline<'a>]), - SpaceAfter(&'a HasAbility<'a>, &'a [CommentOrNewline<'a>]), + SpaceBefore(&'a ImplementsAbility<'a>, &'a [CommentOrNewline<'a>]), + SpaceAfter(&'a ImplementsAbility<'a>, &'a [CommentOrNewline<'a>]), } #[derive(Debug, Copy, Clone, PartialEq)] pub enum HasAbilities<'a> { /// `has [Eq { eq: myEq }, Hash]` - Has(Collection<'a, Loc>>), + Has(Collection<'a, Loc>>), // We preserve this for the formatter; canonicalization ignores it. SpaceBefore(&'a HasAbilities<'a>, &'a [CommentOrNewline<'a>]), @@ -578,7 +578,7 @@ pub enum HasAbilities<'a> { } impl HasAbilities<'_> { - pub fn collection(&self) -> &Collection> { + pub fn collection(&self) -> &Collection> { let mut it = self; loop { match it { @@ -1263,12 +1263,12 @@ impl<'a> Spaceable<'a> for AbilityImpls<'a> { } } -impl<'a> Spaceable<'a> for HasAbility<'a> { +impl<'a> Spaceable<'a> for ImplementsAbility<'a> { fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - HasAbility::SpaceBefore(self, spaces) + ImplementsAbility::SpaceBefore(self, spaces) } fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - HasAbility::SpaceAfter(self, spaces) + ImplementsAbility::SpaceAfter(self, spaces) } } @@ -1368,7 +1368,7 @@ impl_extract_spaces!(Pattern); impl_extract_spaces!(Tag); impl_extract_spaces!(AssignedField); impl_extract_spaces!(TypeAnnotation); -impl_extract_spaces!(HasAbility); +impl_extract_spaces!(ImplementsAbility); impl<'a, T: Copy> ExtractSpaces<'a> for Spaced<'a, T> { type Item = T; @@ -1707,13 +1707,15 @@ impl<'a> Malformed for Implements<'a> { } } -impl<'a> Malformed for HasAbility<'a> { +impl<'a> Malformed for ImplementsAbility<'a> { fn is_malformed(&self) -> bool { match self { - HasAbility::HasAbility { ability, impls } => { + ImplementsAbility::ImplementsAbility { ability, impls } => { ability.is_malformed() || impls.iter().any(|impl_| impl_.is_malformed()) } - HasAbility::SpaceBefore(has, _) | HasAbility::SpaceAfter(has, _) => has.is_malformed(), + ImplementsAbility::SpaceBefore(has, _) | ImplementsAbility::SpaceAfter(has, _) => { + has.is_malformed() + } } } } diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 43fb96c3571..0c4fad8901b 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -1,5 +1,5 @@ use crate::ast::{ - AbilityImpls, AssignedField, CommentOrNewline, Expr, HasAbilities, HasAbility, + AbilityImpls, AssignedField, CommentOrNewline, Expr, HasAbilities, ImplementsAbility, ImplementsClause, Pattern, Spaceable, Spaced, Tag, TypeAnnotation, TypeHeader, }; use crate::blankspace::{ @@ -545,7 +545,7 @@ pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, ETyp loc!(parse_implements_ability()), word1(b',', EType::TEnd), word1(b']', EType::TEnd), - HasAbility::SpaceBefore + ImplementsAbility::SpaceBefore ), HasAbilities::Has )), @@ -554,8 +554,8 @@ pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, ETyp )) } -fn parse_implements_ability<'a>() -> impl Parser<'a, HasAbility<'a>, EType<'a>> { - increment_min_indent(record!(HasAbility::HasAbility { +fn parse_implements_ability<'a>() -> impl Parser<'a, ImplementsAbility<'a>, EType<'a>> { + increment_min_indent(record!(ImplementsAbility::ImplementsAbility { ability: loc!(specialize(EType::TApply, concrete_type())), impls: optional(backtrackable(space0_before_e( loc!(map!( From 4b90948fcfc4cdbd3a4306b21aeae2c22796cacf Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 19:13:01 -0400 Subject: [PATCH 08/55] ast::HasAbilities -> ast::ImplementsAbilities --- crates/compiler/can/src/def.rs | 8 +++---- crates/compiler/fmt/src/annotation.rs | 16 ++++++------- crates/compiler/fmt/src/spaces.rs | 15 ++++++------ crates/compiler/parse/src/ast.rs | 24 +++++++++++--------- crates/compiler/parse/src/expr.rs | 14 ++++++++---- crates/compiler/parse/src/type_annotation.rs | 6 ++--- 6 files changed, 46 insertions(+), 37 deletions(-) diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 14bd8086c9d..140da5955ef 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -174,7 +174,7 @@ enum PendingTypeDef<'a> { name: Loc, vars: Vec>, ann: &'a Loc>, - derived: Option<&'a Loc>>, + derived: Option<&'a Loc>>, }, Ability { @@ -672,7 +672,7 @@ fn canonicalize_opaque<'a>( name_str: &'a str, ann: &'a Loc>, vars: &[Loc], - has_abilities: Option<&'a Loc>>, + has_abilities: Option<&'a Loc>>, ) -> Result, ()> { let alias = canonicalize_alias( env, @@ -1182,7 +1182,7 @@ fn canonicalize_type_defs<'a>( Loc, Vec>, &'a Loc>, - Option<&'a Loc>>, + Option<&'a Loc>>, ), Ability(Loc, Vec>), } @@ -2492,7 +2492,7 @@ fn to_pending_alias_or_opaque<'a>( name: &'a Loc<&'a str>, vars: &'a [Loc>], ann: &'a Loc>, - opt_derived: Option<&'a Loc>>, + opt_derived: Option<&'a Loc>>, kind: AliasKind, ) -> PendingTypeDef<'a> { let region = Region::span_across(&name.region, &ann.region); diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index f66ede894d5..8909b3345d9 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -4,8 +4,8 @@ use crate::{ Buf, }; use roc_parse::ast::{ - AbilityImpls, AssignedField, Collection, Expr, ExtractSpaces, HasAbilities, ImplementsAbility, - ImplementsClause, RecordBuilderField, Tag, TypeAnnotation, TypeHeader, + AbilityImpls, AssignedField, Collection, Expr, ExtractSpaces, ImplementsAbilities, + ImplementsAbility, ImplementsClause, RecordBuilderField, Tag, TypeAnnotation, TypeHeader, }; use roc_parse::ident::UppercaseIdent; use roc_region::all::Loc; @@ -736,17 +736,17 @@ impl<'a> Formattable for ImplementsAbility<'a> { } } -impl<'a> Formattable for HasAbilities<'a> { +impl<'a> Formattable for ImplementsAbilities<'a> { fn is_multiline(&self) -> bool { match self { - HasAbilities::SpaceAfter(..) | HasAbilities::SpaceBefore(..) => true, - HasAbilities::Has(has_abilities) => is_collection_multiline(has_abilities), + ImplementsAbilities::SpaceAfter(..) | ImplementsAbilities::SpaceBefore(..) => true, + ImplementsAbilities::Has(has_abilities) => is_collection_multiline(has_abilities), } } fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) { match self { - HasAbilities::Has(has_abilities) => { + ImplementsAbilities::Has(has_abilities) => { if newlines == Newlines::Yes { buf.newline(); buf.indent(indent); @@ -755,13 +755,13 @@ impl<'a> Formattable for HasAbilities<'a> { buf.spaces(1); fmt_collection(buf, indent, Braces::Square, *has_abilities, Newlines::No); } - HasAbilities::SpaceBefore(has_abilities, spaces) => { + ImplementsAbilities::SpaceBefore(has_abilities, spaces) => { buf.newline(); buf.indent(indent); fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent); has_abilities.format_with_options(buf, parens, Newlines::No, indent) } - HasAbilities::SpaceAfter(has_abilities, spaces) => { + ImplementsAbilities::SpaceAfter(has_abilities, spaces) => { has_abilities.format_with_options(buf, parens, newlines, indent); fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent); } diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index ed2d79adc42..ad94739c721 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -4,9 +4,9 @@ use roc_module::called_via::{BinOp, UnaryOp}; use roc_parse::{ ast::{ AbilityImpls, AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr, - HasAbilities, Header, Implements, ImplementsAbility, ImplementsClause, Module, Pattern, - RecordBuilderField, Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, - TypeHeader, ValueDef, WhenBranch, + Header, Implements, ImplementsAbilities, ImplementsAbility, ImplementsClause, Module, + Pattern, RecordBuilderField, Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, + TypeDef, TypeHeader, ValueDef, WhenBranch, }, header::{ AppHeader, ExposedName, HostedHeader, ImportsEntry, InterfaceHeader, KeywordItem, @@ -914,13 +914,14 @@ impl<'a> RemoveSpaces<'a> for ImplementsAbility<'a> { } } -impl<'a> RemoveSpaces<'a> for HasAbilities<'a> { +impl<'a> RemoveSpaces<'a> for ImplementsAbilities<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { match *self { - HasAbilities::Has(derived) => HasAbilities::Has(derived.remove_spaces(arena)), - HasAbilities::SpaceBefore(derived, _) | HasAbilities::SpaceAfter(derived, _) => { - derived.remove_spaces(arena) + ImplementsAbilities::Has(derived) => { + ImplementsAbilities::Has(derived.remove_spaces(arena)) } + ImplementsAbilities::SpaceBefore(derived, _) + | ImplementsAbilities::SpaceAfter(derived, _) => derived.remove_spaces(arena), } } } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index b995297a465..fbde09ecb6b 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -394,7 +394,7 @@ pub enum TypeDef<'a> { Opaque { header: TypeHeader<'a>, typ: Loc>, - derived: Option>>, + derived: Option>>, }, /// An ability definition. E.g. @@ -568,16 +568,16 @@ pub enum ImplementsAbility<'a> { } #[derive(Debug, Copy, Clone, PartialEq)] -pub enum HasAbilities<'a> { +pub enum ImplementsAbilities<'a> { /// `has [Eq { eq: myEq }, Hash]` Has(Collection<'a, Loc>>), // We preserve this for the formatter; canonicalization ignores it. - SpaceBefore(&'a HasAbilities<'a>, &'a [CommentOrNewline<'a>]), - SpaceAfter(&'a HasAbilities<'a>, &'a [CommentOrNewline<'a>]), + SpaceBefore(&'a ImplementsAbilities<'a>, &'a [CommentOrNewline<'a>]), + SpaceAfter(&'a ImplementsAbilities<'a>, &'a [CommentOrNewline<'a>]), } -impl HasAbilities<'_> { +impl ImplementsAbilities<'_> { pub fn collection(&self) -> &Collection> { let mut it = self; loop { @@ -1272,12 +1272,12 @@ impl<'a> Spaceable<'a> for ImplementsAbility<'a> { } } -impl<'a> Spaceable<'a> for HasAbilities<'a> { +impl<'a> Spaceable<'a> for ImplementsAbilities<'a> { fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - HasAbilities::SpaceBefore(self, spaces) + ImplementsAbilities::SpaceBefore(self, spaces) } fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self { - HasAbilities::SpaceAfter(self, spaces) + ImplementsAbilities::SpaceAfter(self, spaces) } } @@ -1720,11 +1720,13 @@ impl<'a> Malformed for ImplementsAbility<'a> { } } -impl<'a> Malformed for HasAbilities<'a> { +impl<'a> Malformed for ImplementsAbilities<'a> { fn is_malformed(&self) -> bool { match self { - HasAbilities::Has(abilities) => abilities.iter().any(|ability| ability.is_malformed()), - HasAbilities::SpaceBefore(has, _) | HasAbilities::SpaceAfter(has, _) => { + ImplementsAbilities::Has(abilities) => { + abilities.iter().any(|ability| ability.is_malformed()) + } + ImplementsAbilities::SpaceBefore(has, _) | ImplementsAbilities::SpaceAfter(has, _) => { has.is_malformed() } } diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 62a2159050f..5cfc9983111 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1,6 +1,6 @@ use crate::ast::{ - AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces, HasAbilities, - Implements, Pattern, RecordBuilderField, Spaceable, Spaces, TypeAnnotation, TypeDef, + AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces, Implements, + ImplementsAbilities, Pattern, RecordBuilderField, Spaceable, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef, }; use crate::blankspace::{ @@ -1064,8 +1064,14 @@ fn alias_signature_with_space_before<'a>() -> impl Parser<'a, Loc( -) -> impl Parser<'a, (Loc>, Option>>), EExpr<'a>> { +fn opaque_signature_with_space_before<'a>() -> impl Parser< + 'a, + ( + Loc>, + Option>>, + ), + EExpr<'a>, +> { and!( specialize( EExpr::Type, diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 0c4fad8901b..78e03c03b2b 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -1,5 +1,5 @@ use crate::ast::{ - AbilityImpls, AssignedField, CommentOrNewline, Expr, HasAbilities, ImplementsAbility, + AbilityImpls, AssignedField, CommentOrNewline, Expr, ImplementsAbilities, ImplementsAbility, ImplementsClause, Pattern, Spaceable, Spaced, Tag, TypeAnnotation, TypeHeader, }; use crate::blankspace::{ @@ -521,7 +521,7 @@ fn implements_clause_chain<'a>( } /// Parse a implements-abilities clause, e.g. `implements [Eq, Hash]`. -pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { +pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { increment_min_indent(skip_first!( // Parse "implements"; we don't care about this keyword word10( @@ -547,7 +547,7 @@ pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, ETyp word1(b']', EType::TEnd), ImplementsAbility::SpaceBefore ), - HasAbilities::Has + ImplementsAbilities::Has )), EType::TIndentEnd, ) From 10d92bf0f38a87ddfebd00854a8485ae0287efbb Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 19:16:13 -0400 Subject: [PATCH 09/55] ast::ImplementsAbilities::Has -> ast::ImplementsAbilities::Implements --- crates/compiler/fmt/src/annotation.rs | 6 ++++-- crates/compiler/fmt/src/spaces.rs | 4 ++-- crates/compiler/parse/src/ast.rs | 6 +++--- crates/compiler/parse/src/type_annotation.rs | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 8909b3345d9..78ae3eb5d5a 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -740,13 +740,15 @@ impl<'a> Formattable for ImplementsAbilities<'a> { fn is_multiline(&self) -> bool { match self { ImplementsAbilities::SpaceAfter(..) | ImplementsAbilities::SpaceBefore(..) => true, - ImplementsAbilities::Has(has_abilities) => is_collection_multiline(has_abilities), + ImplementsAbilities::Implements(has_abilities) => { + is_collection_multiline(has_abilities) + } } } fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) { match self { - ImplementsAbilities::Has(has_abilities) => { + ImplementsAbilities::Implements(has_abilities) => { if newlines == Newlines::Yes { buf.newline(); buf.indent(indent); diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index ad94739c721..450963fe9d2 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -917,8 +917,8 @@ impl<'a> RemoveSpaces<'a> for ImplementsAbility<'a> { impl<'a> RemoveSpaces<'a> for ImplementsAbilities<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { match *self { - ImplementsAbilities::Has(derived) => { - ImplementsAbilities::Has(derived.remove_spaces(arena)) + ImplementsAbilities::Implements(derived) => { + ImplementsAbilities::Implements(derived.remove_spaces(arena)) } ImplementsAbilities::SpaceBefore(derived, _) | ImplementsAbilities::SpaceAfter(derived, _) => derived.remove_spaces(arena), diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index fbde09ecb6b..c58dedbfdbf 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -570,7 +570,7 @@ pub enum ImplementsAbility<'a> { #[derive(Debug, Copy, Clone, PartialEq)] pub enum ImplementsAbilities<'a> { /// `has [Eq { eq: myEq }, Hash]` - Has(Collection<'a, Loc>>), + Implements(Collection<'a, Loc>>), // We preserve this for the formatter; canonicalization ignores it. SpaceBefore(&'a ImplementsAbilities<'a>, &'a [CommentOrNewline<'a>]), @@ -585,7 +585,7 @@ impl ImplementsAbilities<'_> { Self::SpaceBefore(inner, _) | Self::SpaceAfter(inner, _) => { it = inner; } - Self::Has(collection) => return collection, + Self::Implements(collection) => return collection, } } } @@ -1723,7 +1723,7 @@ impl<'a> Malformed for ImplementsAbility<'a> { impl<'a> Malformed for ImplementsAbilities<'a> { fn is_malformed(&self) -> bool { match self { - ImplementsAbilities::Has(abilities) => { + ImplementsAbilities::Implements(abilities) => { abilities.iter().any(|ability| ability.is_malformed()) } ImplementsAbilities::SpaceBefore(has, _) | ImplementsAbilities::SpaceAfter(has, _) => { diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 78e03c03b2b..92ec2404c12 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -547,7 +547,7 @@ pub fn implements_abilities<'a>() -> impl Parser<'a, Loc word1(b']', EType::TEnd), ImplementsAbility::SpaceBefore ), - ImplementsAbilities::Has + ImplementsAbilities::Implements )), EType::TIndentEnd, ) From d700a6a6e6d5d57f3745deab9713b915f564a99f Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 19:19:11 -0400 Subject: [PATCH 10/55] has -> implements in comments --- crates/compiler/parse/src/ast.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index c58dedbfdbf..855441d39c1 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -365,7 +365,7 @@ pub enum Implements<'a> { SpaceAfter(&'a Implements<'a>, &'a [CommentOrNewline<'a>]), } -/// An ability demand is a value defining the ability; for example `hash : a -> U64 | a has Hash` +/// An ability demand is a value defining the ability; for example `hash : a -> U64 | a implements Hash` /// for a `Hash` ability. #[derive(Debug, Clone, Copy, PartialEq)] pub struct AbilityMember<'a> { @@ -398,8 +398,8 @@ pub enum TypeDef<'a> { }, /// An ability definition. E.g. - /// Hash has - /// hash : a -> U64 | a has Hash + /// Hash implements + /// hash : a -> U64 | a implements Hash Ability { header: TypeHeader<'a>, loc_has: Loc>, @@ -569,7 +569,7 @@ pub enum ImplementsAbility<'a> { #[derive(Debug, Copy, Clone, PartialEq)] pub enum ImplementsAbilities<'a> { - /// `has [Eq { eq: myEq }, Hash]` + /// `implements [Eq { eq: myEq }, Hash]` Implements(Collection<'a, Loc>>), // We preserve this for the formatter; canonicalization ignores it. @@ -641,7 +641,7 @@ pub enum TypeAnnotation<'a> { /// The `*` type variable, e.g. in (List *) Wildcard, - /// A "where" clause demanding abilities designated by a `|`, e.g. `a -> U64 | a has Hash` + /// A "where" clause demanding abilities designated by a `|`, e.g. `a -> U64 | a implements Hash` Where(&'a Loc>, &'a [Loc>]), // We preserve this for the formatter; canonicalization ignores it. From 46cb45f71736a5ba699fd641976474035d077797 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 19:24:08 -0400 Subject: [PATCH 11/55] loc_has -> loc_implements --- crates/compiler/can/src/def.rs | 2 +- crates/compiler/fmt/src/def.rs | 2 +- crates/compiler/fmt/src/spaces.rs | 4 ++-- crates/compiler/parse/src/ast.rs | 4 ++-- crates/compiler/parse/src/expr.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 140da5955ef..e4dee03468a 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -2611,7 +2611,7 @@ fn to_pending_type_def<'a>( Ability { header: TypeHeader { name, vars }, members, - loc_has: _, + loc_implements: _, } => { let name = match scope .introduce_without_shadow_symbol(&Ident::from(name.value), name.region) diff --git a/crates/compiler/fmt/src/def.rs b/crates/compiler/fmt/src/def.rs index bb5268bcc28..b2066f5ffe2 100644 --- a/crates/compiler/fmt/src/def.rs +++ b/crates/compiler/fmt/src/def.rs @@ -123,7 +123,7 @@ impl<'a> Formattable for TypeDef<'a> { } Ability { header: TypeHeader { name, vars }, - loc_has: _, + loc_implements: _, members, } => { buf.indent(indent); diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 450963fe9d2..98ae35ca101 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -507,14 +507,14 @@ impl<'a> RemoveSpaces<'a> for TypeDef<'a> { }, Ability { header: TypeHeader { name, vars }, - loc_has, + loc_implements: loc_has, members, } => Ability { header: TypeHeader { name: name.remove_spaces(arena), vars: vars.remove_spaces(arena), }, - loc_has: loc_has.remove_spaces(arena), + loc_implements: loc_has.remove_spaces(arena), members: members.remove_spaces(arena), }, } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 855441d39c1..88e6db42107 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -402,7 +402,7 @@ pub enum TypeDef<'a> { /// hash : a -> U64 | a implements Hash Ability { header: TypeHeader<'a>, - loc_has: Loc>, + loc_implements: Loc>, members: &'a [AbilityMember<'a>], }, } @@ -1681,7 +1681,7 @@ impl<'a> Malformed for TypeDef<'a> { } => header.is_malformed() || typ.is_malformed() || derived.is_malformed(), TypeDef::Ability { header, - loc_has, + loc_implements: loc_has, members, } => { header.is_malformed() diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 5cfc9983111..7e5cf1a5273 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1408,7 +1408,7 @@ fn finish_parsing_ability_def_help<'a>( let def_region = Region::span_across(&name.region, &demands.last().unwrap().typ.region); let type_def = TypeDef::Ability { header: TypeHeader { name, vars: args }, - loc_has, + loc_implements: loc_has, members: demands.into_bump_slice(), }; From 44d33965089ed047901d3f1333802f108a960052 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 19:47:17 -0400 Subject: [PATCH 12/55] builtin opaque type abilites has -> implements --- crates/compiler/builtins/roc/Bool.roc | 2 +- crates/compiler/builtins/roc/Dict.roc | 4 ++-- crates/compiler/builtins/roc/Json.roc | 2 +- crates/compiler/builtins/roc/Set.roc | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/compiler/builtins/roc/Bool.roc b/crates/compiler/builtins/roc/Bool.roc index 3b425e9bf19..1dbaef12289 100644 --- a/crates/compiler/builtins/roc/Bool.roc +++ b/crates/compiler/builtins/roc/Bool.roc @@ -34,7 +34,7 @@ Eq has ## Represents the boolean true and false using an opaque type. ## `Bool` implements the `Eq` ability. -Bool := [True, False] has [Eq { isEq: boolIsEq }] +Bool := [True, False] implements [Eq { isEq: boolIsEq }] boolIsEq = \@Bool b1, @Bool b2 -> structuralEq b1 b2 diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 57d5091c800..ea25f7df784 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -92,7 +92,7 @@ Dict k v := { # TODO: As an optimization, we can make all of these lists in one allocation # TODO: Grow data with the rest of the hashmap. This will require creating a list of garbage data. # TODO: Change remove to use tombstones. Store the tombstones in a bitmap. - # TODO: define Eq and Hash that are unordered. Only if value has hash/eq? + # TODO: define Eq and Hash that are unordered. Only if value implements hash/eq? metadata : List I8, dataIndices : List Nat, data : List (T k v), @@ -888,7 +888,7 @@ expect # TODO: wyhash is slow for large keys, use something like cityhash if the keys are too long. # TODO: Add a builtin to distinguish big endian systems and change loading orders. # TODO: Switch out Wymum on systems with slow 128bit multiplication. -LowLevelHasher := { originalSeed : U64, state : U64 } has [ +LowLevelHasher := { originalSeed : U64, state : U64 } implements [ Hasher { addBytes, addU8, diff --git a/crates/compiler/builtins/roc/Json.roc b/crates/compiler/builtins/roc/Json.roc index 3cb81ce4bc2..c36b655dfc4 100644 --- a/crates/compiler/builtins/roc/Json.roc +++ b/crates/compiler/builtins/roc/Json.roc @@ -79,7 +79,7 @@ interface Json ## An opaque type with the `EncoderFormatting` and ## `DecoderFormatting` abilities. Json := { fieldNameMapping : FieldNameMapping } - has [ + implements [ EncoderFormatting { u8: encodeU8, u16: encodeU16, diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index c13570c8951..a0f1a8854b6 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -28,8 +28,8 @@ interface Set # | k implements Hash & Eq ## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) ## type which stores a collection of unique values, without any ordering -Set k := Dict.Dict k {} - has [ +Set k := Dict.Dict k {} | k implements Hash & Eq + implements [ Eq { isEq, }, From e04f09231c3fda6fa60ea3422053da5f717d1352 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 21:05:34 -0400 Subject: [PATCH 13/55] has -> implements in error messages --- crates/reporting/src/error/canonicalize.rs | 44 +++++++++++----------- crates/reporting/src/error/type.rs | 18 +++++---- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/crates/reporting/src/error/canonicalize.rs b/crates/reporting/src/error/canonicalize.rs index 30f9e58aae2..70ef2e0dc5e 100644 --- a/crates/reporting/src/error/canonicalize.rs +++ b/crates/reporting/src/error/canonicalize.rs @@ -42,9 +42,9 @@ const OPAQUE_NOT_APPLIED: &str = "OPAQUE TYPE NOT APPLIED"; const OPAQUE_OVER_APPLIED: &str = "OPAQUE TYPE APPLIED TO TOO MANY ARGS"; const INVALID_EXTENSION_TYPE: &str = "INVALID_EXTENSION_TYPE"; const ABILITY_HAS_TYPE_VARIABLES: &str = "ABILITY HAS TYPE VARIABLES"; -const HAS_CLAUSE_IS_NOT_AN_ABILITY: &str = "HAS CLAUSE IS NOT AN ABILITY"; -const ILLEGAL_HAS_CLAUSE: &str = "ILLEGAL HAS CLAUSE"; -const ABILITY_MEMBER_MISSING_HAS_CLAUSE: &str = "ABILITY MEMBER MISSING HAS CLAUSE"; +const IMPLEMENTS_CLAUSE_IS_NOT_AN_ABILITY: &str = "IMPLEMENTS CLAUSE IS NOT AN ABILITY"; +const ILLEGAL_IMPLEMENTS_CLAUSE: &str = "ILLEGAL IMPLEMENTS CLAUSE"; +const ABILITY_MEMBER_MISSING_IMPLEMENTS_CLAUSE: &str = "ABILITY MEMBER MISSING IMPLEMENTS CLAUSE"; const ABILITY_MEMBER_BINDS_MULTIPLE_VARIABLES: &str = "ABILITY MEMBER BINDS MULTIPLE VARIABLES"; const ABILITY_NOT_ON_TOPLEVEL: &str = "ABILITY NOT ON TOP-LEVEL"; const SPECIALIZATION_NOT_ON_TOPLEVEL: &str = "SPECIALIZATION NOT ON TOP-LEVEL"; @@ -652,28 +652,30 @@ pub fn can_problem<'b>( region: clause_region, } => { doc = alloc.stack([ - alloc.reflow(r#"The type referenced in this "has" clause is not an ability:"#), + alloc.reflow( + r#"The type referenced in this "implements" clause is not an ability:"#, + ), alloc.region(lines.convert_region(clause_region)), ]); - title = HAS_CLAUSE_IS_NOT_AN_ABILITY.to_string(); + title = IMPLEMENTS_CLAUSE_IS_NOT_AN_ABILITY.to_string(); } Problem::IllegalHasClause { region } => { doc = alloc.stack([ alloc.concat([ - alloc.reflow("A "), - alloc.keyword("has"), + alloc.reflow("An "), + alloc.keyword("implements"), alloc.reflow(" clause is not allowed here:"), ]), alloc.region(lines.convert_region(region)), alloc.concat([ - alloc.keyword("has"), + alloc.keyword("implements"), alloc.reflow( " clauses can only be specified on the top-level type annotations.", ), ]), ]); - title = ILLEGAL_HAS_CLAUSE.to_string(); + title = ILLEGAL_IMPLEMENTS_CLAUSE.to_string(); } Problem::DuplicateHasAbility { ability, region } => { @@ -685,8 +687,8 @@ pub fn can_problem<'b>( ]), alloc.region(lines.convert_region(region)), alloc.concat([ - alloc.reflow("Abilities only need to bound to a type variable once in a "), - alloc.keyword("has"), + alloc.reflow("Abilities only need to bound to a type variable once in an "), + alloc.keyword("implements"), alloc.reflow(" clause!"), ]), ]); @@ -702,29 +704,29 @@ pub fn can_problem<'b>( alloc.concat([ alloc.reflow("The definition of the ability member "), alloc.symbol_unqualified(member), - alloc.reflow(" does not include a "), - alloc.keyword("has"), + alloc.reflow(" does not include an "), + alloc.keyword("implements"), alloc.reflow(" clause binding a type variable to the ability "), alloc.symbol_unqualified(ability), alloc.reflow(":"), ]), alloc.region(lines.convert_region(region)), alloc.concat([ - alloc.reflow("Ability members must include a "), - alloc.keyword("has"), + alloc.reflow("Ability members must include an "), + alloc.keyword("implements"), alloc.reflow(" clause binding a type variable to an ability, like"), ]), alloc.type_block(alloc.concat([ alloc.type_variable("a".into()), alloc.space(), - alloc.keyword("has"), + alloc.keyword("implements"), alloc.space(), alloc.symbol_unqualified(ability), ])), alloc.concat([alloc .reflow("Otherwise, the function does not need to be part of the ability!")]), ]); - title = ABILITY_MEMBER_MISSING_HAS_CLAUSE.to_string(); + title = ABILITY_MEMBER_MISSING_IMPLEMENTS_CLAUSE.to_string(); } Problem::AbilityMemberMultipleBoundVars { @@ -778,13 +780,13 @@ pub fn can_problem<'b>( ), alloc .hint("") - .append(alloc.reflow("Perhaps you meant to include a ")) - .append(alloc.keyword("has")) + .append(alloc.reflow("Perhaps you meant to include an ")) + .append(alloc.keyword("implements")) .append(alloc.reflow(" annotation, like")), alloc.type_block(alloc.concat([ alloc.type_variable(suggested_var_name), alloc.space(), - alloc.keyword("has"), + alloc.keyword("implements"), alloc.space(), alloc.symbol_unqualified(ability), ])), @@ -851,7 +853,7 @@ pub fn can_problem<'b>( let hint = if ability.is_builtin() { alloc.hint("").append( alloc.reflow("if you want this implementation to be derived, don't include a record of implementations. For example,") - .append(alloc.type_block(alloc.concat([alloc.type_str("has ["), alloc.symbol_unqualified(ability), alloc.type_str("]")]))) + .append(alloc.type_block(alloc.concat([alloc.type_str("implements ["), alloc.symbol_unqualified(ability), alloc.type_str("]")]))) .append(alloc.reflow(" will attempt to derive ").append(alloc.symbol_unqualified(ability)))) } else { alloc.nil() diff --git a/crates/reporting/src/error/type.rs b/crates/reporting/src/error/type.rs index ea2b56d9d82..c039a2770ae 100644 --- a/crates/reporting/src/error/type.rs +++ b/crates/reporting/src/error/type.rs @@ -373,7 +373,7 @@ fn underivable_hint<'b>( alloc.concat([ alloc.reflow(" or "), alloc.inline_type_block(alloc.concat([ - alloc.keyword("has"), + alloc.keyword("implements"), alloc.space(), alloc.symbol_qualified(ability), ])), @@ -400,13 +400,13 @@ fn underivable_hint<'b>( alloc.reflow("This type variable is not bound to "), alloc.symbol_unqualified(ability), alloc.reflow(". Consider adding a "), - alloc.keyword("has"), + alloc.keyword("implements"), alloc.reflow(" clause to bind the type variable, like "), alloc.inline_type_block(alloc.concat([ alloc.string("| ".to_string()), alloc.type_variable(v.clone()), alloc.space(), - alloc.keyword("has"), + alloc.keyword("implements"), alloc.space(), alloc.symbol_qualified(ability), ])), @@ -2758,7 +2758,7 @@ fn type_with_able_vars<'b>( doc.push(alloc.string(if i == 0 { " | " } else { ", " }.to_string())); doc.push(alloc.type_variable(var)); doc.push(alloc.space()); - doc.push(alloc.keyword("has")); + doc.push(alloc.keyword("implements")); for (i, ability) in abilities.into_sorted_iter().enumerate() { if i > 0 { @@ -4468,7 +4468,7 @@ fn type_problem_to_pretty<'b>( .note("") .append(alloc.reflow("The type variable ")) .append(alloc.type_variable(name.clone())) - .append(alloc.reflow(" says it can take on any value that has the ")) + .append(alloc.reflow(" says it can take on any value that implements the ")) .append(list_abilities(alloc, &abilities)) .append(alloc.reflow(".")), alloc.concat([ @@ -4509,11 +4509,13 @@ fn type_problem_to_pretty<'b>( alloc .note("") .append(type_var_doc) - .append(alloc.reflow(" can take on any value that has only the ")) + .append( + alloc.reflow(" can take on any value that implements only the "), + ) .append(list_abilities(alloc, &abilities)) .append(alloc.reflow(".")), alloc.concat([ - alloc.reflow("But, I see that it's also used as if it has the "), + alloc.reflow("But, I see that it's also used as if it implements the "), list_abilities(alloc, &extra_abilities), alloc.reflow(". Can you use "), alloc.type_variable(name.clone()), @@ -4530,7 +4532,7 @@ fn type_problem_to_pretty<'b>( alloc.reflow("it") }, alloc.reflow(" to the "), - alloc.keyword("has"), + alloc.keyword("implements"), alloc.reflow(" clause of "), alloc.type_variable(name), alloc.reflow("."), From 17c733ec81ecd359d37c3abb86e71e0a58323e45 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 21:12:26 -0400 Subject: [PATCH 14/55] has -> implements in roc_problem::can::Problem --- crates/compiler/can/src/annotation.rs | 8 +++---- crates/compiler/can/src/def.rs | 4 ++-- crates/compiler/problem/src/can.rs | 28 +++++++++++----------- crates/reporting/src/error/canonicalize.rs | 10 ++++---- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/crates/compiler/can/src/annotation.rs b/crates/compiler/can/src/annotation.rs index 85d4501cf16..63e9b8ef340 100644 --- a/crates/compiler/can/src/annotation.rs +++ b/crates/compiler/can/src/annotation.rs @@ -1041,7 +1041,7 @@ fn can_annotation_help( debug_assert!(!clauses.is_empty()); // Has clauses are allowed only on the top level of a signature, which we handle elsewhere. - env.problem(roc_problem::can::Problem::IllegalHasClause { + env.problem(roc_problem::can::Problem::IllegalImplementsClause { region: Region::across_all(clauses.iter().map(|clause| &clause.region)), }); @@ -1096,13 +1096,13 @@ fn canonicalize_has_clause( // or an ability that was imported from elsewhere && !scope.abilities_store.is_ability(symbol) { - env.problem(roc_problem::can::Problem::HasClauseIsNotAbility { region }); + env.problem(roc_problem::can::Problem::ImplementsClauseIsNotAbility { region }); return Err(Type::Error); } symbol } _ => { - env.problem(roc_problem::can::Problem::HasClauseIsNotAbility { region }); + env.problem(roc_problem::can::Problem::ImplementsClauseIsNotAbility { region }); return Err(Type::Error); } }; @@ -1111,7 +1111,7 @@ fn canonicalize_has_clause( let already_seen = can_abilities.insert(ability); if already_seen { - env.problem(roc_problem::can::Problem::DuplicateHasAbility { ability, region }); + env.problem(roc_problem::can::Problem::DuplicateImplementsAbility { ability, region }); } } diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index e4dee03468a..41d4800cfb6 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -1388,7 +1388,7 @@ fn resolve_abilities( [] => { // There are no variables bound to the parent ability - then this member doesn't // need to be a part of the ability. - env.problem(Problem::AbilityMemberMissingHasClause { + env.problem(Problem::AbilityMemberMissingImplementsClause { member: member_sym, ability, region: member_name_region, @@ -1411,7 +1411,7 @@ fn resolve_abilities( env.problem(Problem::AbilityMemberMultipleBoundVars { member: member_sym, ability, - span_has_clauses, + span_implements_clauses: span_has_clauses, bound_var_names, }); // Pretend the member isn't a part of the ability diff --git a/crates/compiler/problem/src/can.rs b/crates/compiler/problem/src/can.rs index a81784b239c..2136f7314f4 100644 --- a/crates/compiler/problem/src/can.rs +++ b/crates/compiler/problem/src/can.rs @@ -117,17 +117,17 @@ pub enum Problem { name: Symbol, variables_region: Region, }, - HasClauseIsNotAbility { + ImplementsClauseIsNotAbility { region: Region, }, - IllegalHasClause { + IllegalImplementsClause { region: Region, }, - DuplicateHasAbility { + DuplicateImplementsAbility { ability: Symbol, region: Region, }, - AbilityMemberMissingHasClause { + AbilityMemberMissingImplementsClause { member: Symbol, ability: Symbol, region: Region, @@ -135,7 +135,7 @@ pub enum Problem { AbilityMemberMultipleBoundVars { member: Symbol, ability: Symbol, - span_has_clauses: Region, + span_implements_clauses: Region, bound_var_names: Vec, }, AbilityNotOnToplevel { @@ -245,10 +245,10 @@ impl Problem { Problem::NestedDatatype { .. } => RuntimeError, Problem::InvalidExtensionType { .. } => RuntimeError, Problem::AbilityHasTypeVariables { .. } => RuntimeError, - Problem::HasClauseIsNotAbility { .. } => RuntimeError, - Problem::IllegalHasClause { .. } => RuntimeError, - Problem::DuplicateHasAbility { .. } => Warning, - Problem::AbilityMemberMissingHasClause { .. } => RuntimeError, + Problem::ImplementsClauseIsNotAbility { .. } => RuntimeError, + Problem::IllegalImplementsClause { .. } => RuntimeError, + Problem::DuplicateImplementsAbility { .. } => Warning, + Problem::AbilityMemberMissingImplementsClause { .. } => RuntimeError, Problem::AbilityMemberMultipleBoundVars { .. } => RuntimeError, Problem::AbilityNotOnToplevel { .. } => RuntimeError, // Ideally, could be compiled Problem::AbilityUsedAsType(_, _, _) => RuntimeError, @@ -375,12 +375,12 @@ impl Problem { variables_region: region, .. } - | Problem::HasClauseIsNotAbility { region } - | Problem::IllegalHasClause { region } - | Problem::DuplicateHasAbility { region, .. } - | Problem::AbilityMemberMissingHasClause { region, .. } + | Problem::ImplementsClauseIsNotAbility { region } + | Problem::IllegalImplementsClause { region } + | Problem::DuplicateImplementsAbility { region, .. } + | Problem::AbilityMemberMissingImplementsClause { region, .. } | Problem::AbilityMemberMultipleBoundVars { - span_has_clauses: region, + span_implements_clauses: region, .. } | Problem::AbilityNotOnToplevel { region } diff --git a/crates/reporting/src/error/canonicalize.rs b/crates/reporting/src/error/canonicalize.rs index 70ef2e0dc5e..a3332a06f29 100644 --- a/crates/reporting/src/error/canonicalize.rs +++ b/crates/reporting/src/error/canonicalize.rs @@ -648,7 +648,7 @@ pub fn can_problem<'b>( title = ABILITY_HAS_TYPE_VARIABLES.to_string(); } - Problem::HasClauseIsNotAbility { + Problem::ImplementsClauseIsNotAbility { region: clause_region, } => { doc = alloc.stack([ @@ -660,7 +660,7 @@ pub fn can_problem<'b>( title = IMPLEMENTS_CLAUSE_IS_NOT_AN_ABILITY.to_string(); } - Problem::IllegalHasClause { region } => { + Problem::IllegalImplementsClause { region } => { doc = alloc.stack([ alloc.concat([ alloc.reflow("An "), @@ -678,7 +678,7 @@ pub fn can_problem<'b>( title = ILLEGAL_IMPLEMENTS_CLAUSE.to_string(); } - Problem::DuplicateHasAbility { ability, region } => { + Problem::DuplicateImplementsAbility { ability, region } => { doc = alloc.stack([ alloc.concat([ alloc.reflow("I already saw that this type variable is bound to the "), @@ -695,7 +695,7 @@ pub fn can_problem<'b>( title = "DUPLICATE BOUND ABILITY".to_string(); } - Problem::AbilityMemberMissingHasClause { + Problem::AbilityMemberMissingImplementsClause { member, ability, region, @@ -732,7 +732,7 @@ pub fn can_problem<'b>( Problem::AbilityMemberMultipleBoundVars { member, ability, - span_has_clauses, + span_implements_clauses: span_has_clauses, mut bound_var_names, } => { doc = alloc.stack([ From 43e6cf6f907934c7958690f8bde2db73a5872091 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 20 May 2023 21:36:55 -0400 Subject: [PATCH 15/55] Fix typo --- crates/reporting/src/error/type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/reporting/src/error/type.rs b/crates/reporting/src/error/type.rs index c039a2770ae..9647b0208b7 100644 --- a/crates/reporting/src/error/type.rs +++ b/crates/reporting/src/error/type.rs @@ -399,7 +399,7 @@ fn underivable_hint<'b>( Some(alloc.tip().append(alloc.concat([ alloc.reflow("This type variable is not bound to "), alloc.symbol_unqualified(ability), - alloc.reflow(". Consider adding a "), + alloc.reflow(". Consider adding an "), alloc.keyword("implements"), alloc.reflow(" clause to bind the type variable, like "), alloc.inline_type_block(alloc.concat([ From 95516d585afcafdaae7a7757f6401ab28bdd1a4f Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sun, 21 May 2023 19:03:53 -0400 Subject: [PATCH 16/55] Update formatter `has` -> `implements` --- crates/compiler/fmt/src/annotation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 78ae3eb5d5a..7b6c969dadf 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -654,7 +654,7 @@ impl<'a> Formattable for ImplementsClause<'a> { fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) { buf.push_str(self.var.value.extract_spaces().item); buf.spaces(1); - buf.push_str("has"); + buf.push_str("implements"); buf.spaces(1); for (i, ab) in self.abilities.iter().enumerate() { @@ -753,7 +753,7 @@ impl<'a> Formattable for ImplementsAbilities<'a> { buf.newline(); buf.indent(indent); } - buf.push_str("has"); + buf.push_str("implements"); buf.spaces(1); fmt_collection(buf, indent, Braces::Square, *has_abilities, Newlines::No); } From 8191c49ab02d9e7e0fe155cde1fda1b675710c92 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sun, 21 May 2023 19:52:49 -0400 Subject: [PATCH 17/55] `has` -> `implements` in reporting tests --- crates/reporting/tests/test_reporting.rs | 317 ++++++++++++----------- 1 file changed, 159 insertions(+), 158 deletions(-) diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 9096c1bf1b7..098e7a7b203 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -6488,7 +6488,7 @@ In roc, functions are always written as a lambda, like{} inference_var_conflict_in_rigid_links, indoc!( r#" - f : a -> (_ -> b) | a has Eq + f : a -> (_ -> b) | a implements Eq f = \x -> \y -> if x == y then x else y f "# @@ -6499,17 +6499,17 @@ In roc, functions are always written as a lambda, like{} Something is off with the body of the `f` definition: - 4│ f : a -> (_ -> b) | a has Eq + 4│ f : a -> (_ -> b) | a implements Eq 5│ f = \x -> \y -> if x == y then x else y ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The body is an anonymous function of type: - a -> a | a has Eq, a has Eq + a -> a | a implements Eq, a implements Eq But the type annotation on `f` says it should be: - a -> b | a has Eq + a -> b | a implements Eq Tip: Your type annotation uses `b` and `a` as separate type variables. Your code seems to be saying they are the same though. Maybe they @@ -8206,8 +8206,8 @@ In roc, functions are always written as a lambda, like{} ability_first_demand_not_indented_enough, indoc!( r#" - MEq has - eq : a, a -> U64 | a has MEq + MEq implements + eq : a, a -> U64 | a implements MEq 1 "# @@ -8218,8 +8218,8 @@ In roc, functions are always written as a lambda, like{} I was partway through parsing an ability definition, but I got stuck here: - 4│ MEq has - 5│ eq : a, a -> U64 | a has MEq + 4│ MEq implements + 5│ eq : a, a -> U64 | a implements MEq ^ I suspect this line is not indented enough (by 1 spaces) @@ -8230,9 +8230,9 @@ In roc, functions are always written as a lambda, like{} ability_demands_not_indented_with_first, indoc!( r#" - MEq has - eq : a, a -> U64 | a has MEq - neq : a, a -> U64 | a has MEq + MEq implements + eq : a, a -> U64 | a implements MEq + neq : a, a -> U64 | a implements MEq 1 "# @@ -8243,8 +8243,8 @@ In roc, functions are always written as a lambda, like{} I was partway through parsing an ability definition, but I got stuck here: - 5│ eq : a, a -> U64 | a has MEq - 6│ neq : a, a -> U64 | a has MEq + 5│ eq : a, a -> U64 | a implements MEq + 6│ neq : a, a -> U64 | a implements MEq ^ I suspect this line is indented too much (by 4 spaces)"# @@ -8254,8 +8254,8 @@ In roc, functions are always written as a lambda, like{} ability_demand_value_has_args, indoc!( r#" - MEq has - eq b c : a, a -> U64 | a has MEq + MEq implements + eq b c : a, a -> U64 | a implements MEq 1 "# @@ -8266,8 +8266,8 @@ In roc, functions are always written as a lambda, like{} I was partway through parsing an ability definition, but I got stuck here: - 4│ MEq has - 5│ eq b c : a, a -> U64 | a has MEq + 4│ MEq implements + 5│ eq b c : a, a -> U64 | a implements MEq ^ I was expecting to see a : annotating the signature of this value @@ -8278,7 +8278,7 @@ In roc, functions are always written as a lambda, like{} ability_non_signature_expression, indoc!( r#" - MEq has + MEq implememts 123 1 @@ -8290,7 +8290,7 @@ In roc, functions are always written as a lambda, like{} I was partway through parsing an ability definition, but I got stuck here: - 4│ MEq has + 4│ MEq implements 5│ 123 ^ @@ -8416,8 +8416,8 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [] to "./platform" - MHash a b c has - hash : a -> U64 | a has MHash + MHash a b c implements + hash : a -> U64 | a implements MHash "# ), @r###" @@ -8425,7 +8425,7 @@ In roc, functions are always written as a lambda, like{} The definition of the `MHash` ability includes type variables: - 3│ MHash a b c has + 3│ MHash a b c implements ^^^^^ Abilities cannot depend on type variables, but their member values @@ -8435,7 +8435,7 @@ In roc, functions are always written as a lambda, like{} `MHash` is not used anywhere in your code. - 3│ MHash a b c has + 3│ MHash a b c implements ^^^^^ If you didn't intend on using `MHash` then remove it so future readers @@ -8449,16 +8449,16 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash] to "./platform" - MHash has hash : a, b -> Num.U64 | a has MHash, b has Bool.Bool + MHash implements hash : a, b -> Num.U64 | a implements MHash, b implements Bool.Bool "# ), @r###" - ── HAS CLAUSE IS NOT AN ABILITY ────────────────────────── /code/proj/Main.roc ─ + ── IMPLEMENTS CLAUSE IS NOT AN ABILITY ──────────────────── /code/proj/Main.roc ─ - The type referenced in this "has" clause is not an ability: + The type referenced in this "implememts" clause is not an ability: - 3│ MHash has hash : a, b -> Num.U64 | a has MHash, b has Bool.Bool - ^^^^^^^^^ + 3│ MHash has hash : a, b -> Num.U64 | a implements MHash, b implements Bool.Bool + ^^^^^^^^^ "### ); @@ -8468,7 +8468,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [ab1] to "./platform" - Ab1 has ab1 : a -> {} | a has Ab1, a has Ab1 + Ab1 implements ab1 : a -> {} | a implements Ab1, a implements Ab1 "# ), @r#" @@ -8476,13 +8476,13 @@ In roc, functions are always written as a lambda, like{} The `a` name is first defined here: - 3│ Ab1 has ab1 : a -> {} | a has Ab1, a has Ab1 - ^^^^^^^^^ + 3│ Ab1 implements ab1 : a -> {} | a implements Ab1, a implements Ab1 + ^^^^^^^^^^^^^^^^ But then it's defined a second time here: - 3│ Ab1 has ab1 : a -> {} | a has Ab1, a has Ab1 - ^^^^^^^^^ + 3│ Ab1 implements ab1 : a -> {} | a implements Ab1, a implements Ab1 + ^^^^^^^^^^^^^^^^ Since these variables have the same name, it's easy to use the wrong one by accident. Give one of them a new name. @@ -8495,9 +8495,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [ab] to "./platform" - Ability has ab : a -> U64 | a has Ability + Ability implements ab : a -> U64 | a implements Ability - Ability has ab1 : a -> U64 | a has Ability + Ability implements ab1 : a -> U64 | a implements Ability "# ), @r#" @@ -8505,12 +8505,12 @@ In roc, functions are always written as a lambda, like{} The `Ability` name is first defined here: - 3│ Ability has ab : a -> U64 | a has Ability + 3│ Ability implements ab : a -> U64 | a implements Ability ^^^^^^^ But then it's defined a second time here: - 5│ Ability has ab1 : a -> U64 | a has Ability + 5│ Ability implements ab1 : a -> U64 | a implements Ability ^^^^^^^ Since these abilities have the same name, it's easy to use the wrong @@ -8524,22 +8524,22 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [] to "./platform" - Ability has ab : {} -> {} + Ability implements ab : {} -> {} "# ), @r#" - ── ABILITY MEMBER MISSING HAS CLAUSE ───────────────────── /code/proj/Main.roc ─ + ── ABILITY MEMBER MISSING IMPLEMENTS CLAUSE ────────────── /code/proj/Main.roc ─ - The definition of the ability member `ab` does not include a `has` clause + The definition of the ability member `ab` does not include an `implements` clause binding a type variable to the ability `Ability`: - 3│ Ability has ab : {} -> {} - ^^ + 3│ Ability implements ab : {} -> {} + ^^ - Ability members must include a `has` clause binding a type variable to + Ability members must include an `implements` clause binding a type variable to an ability, like - a has Ability + a implements Ability Otherwise, the function does not need to be part of the ability! @@ -8547,7 +8547,7 @@ In roc, functions are always written as a lambda, like{} `Ability` is not used anywhere in your code. - 3│ Ability has ab : {} -> {} + 3│ Ability implements ab : {} -> {} ^^^^^^^ If you didn't intend on using `Ability` then remove it so future readers @@ -8561,7 +8561,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [] to "./platform" - MEq has eq : a, b -> Bool.Bool | a has MEq, b has MEq + MEq implements eq : a, b -> Bool.Bool | a implements MEq, b implements MEq "# ), @r#" @@ -8570,8 +8570,8 @@ In roc, functions are always written as a lambda, like{} The definition of the ability member `eq` includes multiple variables bound to the `MEq`` ability:` - 3│ MEq has eq : a, b -> Bool.Bool | a has MEq, b has MEq - ^^^^^^^^^^^^^^^^^^^^ + 3│ MEq implements eq : a, b -> Bool.Bool | a implements MEq, b implements MEq + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ability members can only bind one type variable to their parent ability. Otherwise, I wouldn't know what type implements an ability by @@ -8587,33 +8587,33 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [f] to "./platform" - MHash has hash : (a | a has MHash) -> Num.U64 + MHash implements hash : (a | a implements MHash) -> Num.U64 - f : a -> Num.U64 | a has MHash + f : a -> Num.U64 | a implements MHash "# ), @r###" - ── ILLEGAL HAS CLAUSE ──────────────────────────────────── /code/proj/Main.roc ─ + ── ILLEGAL IMPLEMENTS CLAUSE ───────────────────────────── /code/proj/Main.roc ─ - A `has` clause is not allowed here: + An `implements` clause is not allowed here: - 3│ MHash has hash : (a | a has MHash) -> Num.U64 - ^^^^^^^^^^^ + 3│ MHash implements hash : (a | a implements MHash) -> Num.U64 + ^^^^^^^^^^^^^^^^^^ - `has` clauses can only be specified on the top-level type annotations. + `implements` clauses can only be specified on the top-level type annotations. - ── ABILITY MEMBER MISSING HAS CLAUSE ───────────────────── /code/proj/Main.roc ─ + ── ABILITY MEMBER MISSING IMPLEMENTS CLAUSE ────────────── /code/proj/Main.roc ─ - The definition of the ability member `hash` does not include a `has` + The definition of the ability member `hash` does not include an `implements` clause binding a type variable to the ability `MHash`: - 3│ MHash has hash : (a | a has MHash) -> Num.U64 - ^^^^ + 3│ MHash implements hash : (a | a implements MHash) -> Num.U64 + ^^^^ - Ability members must include a `has` clause binding a type variable to + Ability members must include an `implements` clause binding a type variable to an ability, like - a has MHash + a implements MHash Otherwise, the function does not need to be part of the ability! "### @@ -8625,9 +8625,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash] to "./platform" - MHash has hash : a -> U64 | a has MHash + MHash implements hash : a -> U64 | a implements MHash - Id := U32 has [MHash {hash}] + Id := U32 implements [MHash {hash}] hash = \@Id n -> n "# @@ -8656,11 +8656,11 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [eq, le] to "./platform" - MEq has - eq : a, a -> Bool | a has MEq - le : a, a -> Bool | a has MEq + MEq implements + eq : a, a -> Bool | a implements MEq + le : a, a -> Bool | a implements MEq - Id := U64 has [MEq {eq}] + Id := U64 implements [MEq {eq}] eq = \@Id m, @Id n -> m == n "# @@ -8670,8 +8670,8 @@ In roc, functions are always written as a lambda, like{} This type does not fully implement the `MEq` ability: - 7│ Id := U64 has [MEq {eq}] - ^^^^^^^^ + 7│ Id := U64 implements [MEq {eq}] + ^^^^^^^^ The following necessary members are missing implementations: @@ -8685,8 +8685,8 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash hash = \_ -> 0u64 "# @@ -8710,11 +8710,11 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash, One, Two] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - One := {} has [MHash {hash}] - Two := {} has [MHash {hash}] + One := {} implements [MHash {hash}] + Two := {} implements [MHash {hash}] hash = \_ -> 0u64 "# @@ -8726,8 +8726,8 @@ In roc, functions are always written as a lambda, like{} This ability member specialization is already claimed to specialize another opaque type: - 7│ Two := {} has [MHash {hash}] - ^^^^ + 7│ Two := {} implements [MHash {hash}] + ^^^^ Previously, we found it to specialize `hash` for `One`. @@ -8764,11 +8764,11 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash, One, Two] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - One := {} has [MHash {hash}] - Two := {} has [MHash {hash}] + One := {} implements [MHash {hash}] + Two := {} implements [MHash {hash}] hash = \@One _ -> 0u64 "# @@ -8779,8 +8779,8 @@ In roc, functions are always written as a lambda, like{} This ability member specialization is already claimed to specialize another opaque type: - 7│ Two := {} has [MHash {hash}] - ^^^^ + 7│ Two := {} implements [MHash {hash}] + ^^^^ Previously, we found it to specialize `hash` for `One`. @@ -8795,10 +8795,10 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [eq] to "./platform" - MEq has - eq : a, a -> Bool | a has MEq + MEq implements + eq : a, a -> Bool | a implements MEq - You := {} has [MEq {eq}] + You := {} implements [MEq {eq}] AndI := {} eq = \@You {}, @AndI {} -> False @@ -8831,9 +8831,9 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash] to "./platform" MHash has - hash : a -> U64 | a has MHash + hash : a -> U64 | a implements MHash - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash : Id -> U32 hash = \@Id n -> n @@ -8865,7 +8865,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [noGoodVeryBadTerrible] to "./platform" MHash has - hash : a -> U64 | a has MHash + hash : a -> U64 | a implements MHash Id := U64 has [MHash {hash}] @@ -8913,7 +8913,7 @@ In roc, functions are always written as a lambda, like{} main = MHash has - hash : a -> U64 | a has MHash + hash : a -> U64 | a implements MHash 123 "# @@ -8924,7 +8924,7 @@ In roc, functions are always written as a lambda, like{} This ability definition is not on the top-level of a module: 4│> MHash has - 5│> hash : a -> U64 | a has MHash + 5│> hash : a -> U64 | a implements MHash Abilities can only be defined on the top-level of a Roc module. "# @@ -8937,12 +8937,12 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash, hashable] to "./platform" MHash has - hash : a -> U64 | a has MHash + hash : a -> U64 | a implements MHash Id := U64 has [MHash {hash}] hash = \@Id n -> n - hashable : a | a has MHash + hashable : a | a implements MHash hashable = @Id 15 "# ), @@ -8951,7 +8951,7 @@ In roc, functions are always written as a lambda, like{} Something is off with the body of the `hashable` definition: - 9│ hashable : a | a has MHash + 9│ hashable : a | a implements MHash 10│ hashable = @Id 15 ^^^^^^ @@ -8963,7 +8963,7 @@ In roc, functions are always written as a lambda, like{} a | a has MHash - Note: The type variable `a` says it can take on any value that has the + Note: The type variable `a` says it can take on any value that implements the ability `MHash`. But, I see that the type is only ever used as a a `Id` value. Can you @@ -8978,7 +8978,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [result] to "./platform" MHash has - hash : a -> U64 | a has MHash + hash : a -> U64 | a implements MHash mulMHashes : MHash, MHash -> U64 mulMHashes = \x, y -> hash x * hash y @@ -9003,9 +9003,9 @@ In roc, functions are always written as a lambda, like{} Abilities can only be used in type annotations to constrain type variables. - Hint: Perhaps you meant to include a `has` annotation, like + Hint: Perhaps you meant to include an `implements` annotation, like - a has MHash + a implements MHash ── ABILITY USED AS TYPE ────────────────────────────────── /code/proj/Main.roc ─ @@ -9017,9 +9017,9 @@ In roc, functions are always written as a lambda, like{} Abilities can only be used in type annotations to constrain type variables. - Hint: Perhaps you meant to include a `has` annotation, like + Hint: Perhaps you meant to include an `implements` annotation, like - b has MHash + b implements MHash "### ); @@ -9153,7 +9153,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [main] to "./platform" - Default has default : {} -> a | a has Default + Default has default : {} -> a | a implements Default main = A := {} has [Default {default}] @@ -9404,7 +9404,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> U64 | a has MEq + MEq has eq : a, a -> U64 | a implements MEq A := U8 has [MEq {eq}] "# @@ -9440,7 +9440,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A, myMEq] to "./platform" - MEq has eq : a, a -> Bool | a has MEq + MEq has eq : a, a -> Bool | a implements MEq A := U8 has [ MEq {eq: aMEq} ] @@ -9481,7 +9481,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A, myMEq] to "./platform" - MEq has eq : a, a -> Bool | a has MEq + MEq has eq : a, a -> Bool | a implements MEq A := U8 has [ MEq {eq ? aMEq} ] @@ -9559,7 +9559,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> Bool | a has MEq + MEq has eq : a, a -> Bool | a implements MEq A := U8 has [ MEq {eq : Bool.eq} ] "# @@ -9594,7 +9594,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> Bool | a has MEq + MEq has eq : a, a -> Bool | a implements MEq A := U8 has [ MEq {eq : \m, n -> m == n} ] "# @@ -9631,7 +9631,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> Bool | a has MEq + MEq has eq : a, a -> Bool | a implements MEq A := U8 has [ MEq {eq: eqA, eq: eqA} ] @@ -9684,7 +9684,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - Ab has ab : a -> a | a has Ab + Ab has ab : a -> a | a implements Ab A := {} has [Ab] "# @@ -9945,9 +9945,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [x] to "./platform" - Foo has foo : a -> a | a has Foo + Foo has foo : a -> a | a implements Foo - F a b := b | a has Foo + F a b := b | a implements Foo MHash := {} @@ -10475,7 +10475,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [hash, Id] to "./platform" - MHash has hash : a -> U64 | a has MHash + MHash has hash : a -> U64 | a implements MHash Id := {} @@ -10501,7 +10501,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [hash, Id, Id2] to "./platform" - MHash has hash : a -> U64 | a has MHash + MHash has hash : a -> U64 | a implements MHash Id := {} has [MHash {hash}] Id2 := {} @@ -10657,7 +10657,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder (a -> a) fmt | fmt has DecoderFormatting + myDecoder : Decoder (a -> a) fmt | fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -10688,7 +10688,7 @@ I recommend using camelCase. It's the standard style in Roc code! A := {} main = - myDecoder : Decoder {x : A} fmt | fmt has DecoderFormatting + myDecoder : Decoder {x : A} fmt | fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -10907,7 +10907,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder {x : Str, y ? Str} fmt | fmt has DecoderFormatting + myDecoder : Decoder {x : Str, y ? Str} fmt | fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -11320,7 +11320,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Hash + foo : a -> {} | a implements Hash main = foo {a: "", b: 1} "# @@ -11334,7 +11334,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Hash + foo : a -> {} | a implements Hash t : [A {}, B U8 U64, C Str] @@ -11350,7 +11350,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Hash + foo : a -> {} | a implements Hash main = foo (\x -> x) "# @@ -11377,7 +11377,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Hash + foo : a -> {} | a implements Hash main = foo (A (\x -> x) B) "# @@ -11410,7 +11410,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Hash + foo : a -> {} | a implements Hash main = foo ("", 1) "# @@ -11423,7 +11423,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Hash + foo : a -> {} | a implements Hash main = foo ("", \{} -> {}) "# @@ -11705,7 +11705,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Eq + foo : a -> {} | a implements Eq main = foo {a: "", b: 1} "# @@ -11719,7 +11719,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Eq + foo : a -> {} | a implements Eq t : [A {}, B U8 U64, C Str] @@ -11735,7 +11735,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Eq + foo : a -> {} | a implements Eq main = foo (\x -> x) "# @@ -11762,7 +11762,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Eq + foo : a -> {} | a implements Eq main = foo (A (\x -> x) B) "# @@ -11841,7 +11841,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Eq + foo : a -> {} | a implements Eq main = foo ("", 1) "# @@ -11854,7 +11854,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a has Eq + foo : a -> {} | a implements Eq main = foo ("", 1.0f64) "# @@ -11934,7 +11934,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [f] to "./platform" - F a : a | a has Hash + F a : a | a implements Hash f : F ({} -> {}) "# @@ -12033,7 +12033,7 @@ I recommend using camelCase. It's the standard style in Roc code! duplicate_ability_in_has_clause, indoc!( r#" - f : a -> {} | a has Hash & Hash + f : a -> {} | a implements Hash & Hash f "# @@ -12044,10 +12044,10 @@ I recommend using camelCase. It's the standard style in Roc code! I already saw that this type variable is bound to the `Hash` ability once before: - 4│ f : a -> {} | a has Hash & Hash - ^^^^ + 4│ f : a -> {} | a implements Hash & Hash + ^^^^ - Abilities only need to bound to a type variable once in a `has` clause! + Abilities only need to bound to a type variable once in an `implements` clause! "### ); @@ -12057,9 +12057,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - g : x -> x | x has Decoding & Encoding + g : x -> x | x implements Decoding & Encoding - main : x -> x | x has Encoding + main : x -> x | x implements Encoding main = \x -> g x "# ), @@ -12073,17 +12073,17 @@ I recommend using camelCase. It's the standard style in Roc code! This `x` value is a: - x | x has Encoding + x | x implements Encoding But `g` needs its 1st argument to be: - x | x has Encoding & Decoding + x | x implements Encoding & Decoding Note: The type variable `x` says it can take on any value that has only the ability `Encoding`. - But, I see that it's also used as if it has the ability `Decoding`. Can - you use `x` without that ability? If not, consider adding it to the `has` + But, I see that it's also used as if it implements the ability `Decoding`. Can + you use `x` without that ability? If not, consider adding it to the `implements` clause of `x`. "### ); @@ -12094,9 +12094,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - g : x -> x | x has Decoding & Encoding & Hash + g : x -> x | x implements Decoding & Encoding & Hash - main : x -> x | x has Encoding + main : x -> x | x implements Encoding main = \x -> g x "# ), @@ -12110,18 +12110,18 @@ I recommend using camelCase. It's the standard style in Roc code! This `x` value is a: - x | x has Encoding + x | x implements Encoding But `g` needs its 1st argument to be: - x | x has Hash & Encoding & Decoding + x | x implements Hash & Encoding & Decoding - Note: The type variable `x` says it can take on any value that has only + Note: The type variable `x` says it can take on any value that implements only the ability `Encoding`. - But, I see that it's also used as if it has the abilities `Hash` and + But, I see that it's also used as if it implements the abilities `Hash` and `Decoding`. Can you use `x` without those abilities? If not, consider - adding them to the `has` clause of `x`. + adding them to the `implements` clause of `x`. "### ); @@ -12131,10 +12131,10 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - f : x -> x | x has Hash - g : x -> x | x has Decoding & Encoding + f : x -> x | x implements Hash + g : x -> x | x implements Decoding & Encoding - main : x -> x | x has Hash & Encoding + main : x -> x | x implements Hash & Encoding main = \x -> g (f x) "# ), @@ -12148,17 +12148,17 @@ I recommend using camelCase. It's the standard style in Roc code! This `f` call produces: - x | x has Hash & Encoding + x | x implements Hash & Encoding But `g` needs its 1st argument to be: - x | x has Encoding & Decoding + x | x implements Encoding & Decoding - Note: The type variable `x` says it can take on any value that has only + Note: The type variable `x` says it can take on any value that implements only the abilities `Hash` and `Encoding`. - But, I see that it's also used as if it has the ability `Decoding`. Can - you use `x` without that ability? If not, consider adding it to the `has` + But, I see that it's also used as if it implements the ability `Decoding`. Can + you use `x` without that ability? If not, consider adding it to the `implements` clause of `x`. "### ); @@ -12898,8 +12898,9 @@ I recommend using camelCase. It's the standard style in Roc code! cannot be generated. - Tip: This type variable is not bound to `Eq`. Consider adding a `has` - clause to bind the type variable, like `| e has Bool.Eq` + Tip: This type variable is not bound to `Eq`. Consider adding an + `implements` clause to bind the type variable, like + `| e implements Bool.Eq` "### ); @@ -13365,7 +13366,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder Nat fmt | fmt has DecoderFormatting + myDecoder : Decoder Nat fmt | fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -13429,7 +13430,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder (U32, Str) fmt | fmt has DecoderFormatting + myDecoder : Decoder (U32, Str) fmt | fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -13444,7 +13445,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder (U32, {} -> {}) fmt | fmt has DecoderFormatting + myDecoder : Decoder (U32, {} -> {}) fmt | fmt implements DecoderFormatting myDecoder = decoder myDecoder From 31c06ca9793a17cdb06f333cc8fa0a7ffdaa7072 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sun, 21 May 2023 19:54:58 -0400 Subject: [PATCH 18/55] `has` -> `implements` --- crates/compiler/solve/tests/solve_expr.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 58cf662de3b..584d7f10368 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -3411,7 +3411,7 @@ mod solve_expr { infer_eq_without_problem( indoc!( r#" - 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 KeyNotFound -> @@ -3458,7 +3458,7 @@ mod solve_expr { Model position : { openSet : Set position } - cheapestOpen : Model position -> Result position [KeyNotFound] | position has Hash & Eq + cheapestOpen : Model position -> Result position [KeyNotFound] | position implements Hash & Eq cheapestOpen = \model -> folder = \resSmallestSoFar, position -> @@ -3473,7 +3473,7 @@ mod solve_expr { Set.walk model.openSet (Ok { position: boom {}, cost: 0.0 }) folder |> Result.map (\x -> x.position) - astar : Model position -> Result position [KeyNotFound] | position has Hash & Eq + astar : Model position -> Result position [KeyNotFound] | position implements Hash & Eq astar = \model -> cheapestOpen model main = @@ -4122,7 +4122,7 @@ mod solve_expr { Key k : Num k - removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v | k has Hash & Eq + removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v | k implements Hash & Eq removeHelpEQGT = \targetKey, dict -> when dict is Node color key value left right -> @@ -4236,7 +4236,7 @@ mod solve_expr { _ -> Empty - removeHelp : Key k, RBTree (Key k) v -> RBTree (Key k) v | k has Hash & Eq + removeHelp : Key k, RBTree (Key k) v -> RBTree (Key k) v | k implements Hash & Eq removeHelp = \targetKey, dict -> when dict is Empty -> @@ -4324,7 +4324,7 @@ mod solve_expr { RBTree k v : [Node NodeColor k v (RBTree k v) (RBTree k v), Empty] - removeHelp : Num k, RBTree (Num k) v -> RBTree (Num k) v | k has Hash & Eq + removeHelp : Num k, RBTree (Num k) v -> RBTree (Num k) v | k implements Hash & Eq removeHelp = \targetKey, dict -> when dict is Empty -> @@ -4359,7 +4359,7 @@ mod solve_expr { removeHelpPrepEQGT : Key k, RBTree (Key k) v, NodeColor, (Key k), v, RBTree (Key k) v, RBTree (Key k) v -> RBTree (Key k) v - removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v | k has Hash & Eq + removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v | k implements Hash & Eq removeHelpEQGT = \targetKey, dict -> when dict is Node color key value left right -> From 9bd207701011e2b82a05f2abadb78908976b919b Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Mon, 22 May 2023 21:59:02 -0400 Subject: [PATCH 19/55] `has [...]` -> `implements [...]` --- crates/reporting/tests/test_reporting.rs | 200 +++++++++++------------ 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 098e7a7b203..0bfef5101cf 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -8747,7 +8747,7 @@ In roc, functions are always written as a lambda, like{} But the type annotation on `hash` says it must match: - a -> U64 | a has MHash + a -> U64 | a implements MHash Note: The specialized type is too general, and does not provide a concrete type where a type variable is bound to an ability. @@ -8867,7 +8867,7 @@ In roc, functions are always written as a lambda, like{} MHash has hash : a -> U64 | a implements MHash - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash = \@Id n -> n @@ -8939,7 +8939,7 @@ In roc, functions are always written as a lambda, like{} MHash has hash : a -> U64 | a implements MHash - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash = \@Id n -> n hashable : a | a implements MHash @@ -8961,7 +8961,7 @@ In roc, functions are always written as a lambda, like{} But the type annotation on `hashable` says it should be: - a | a has MHash + a | a implements MHash Note: The type variable `a` says it can take on any value that implements the ability `MHash`. @@ -8983,10 +8983,10 @@ In roc, functions are always written as a lambda, like{} mulMHashes : MHash, MHash -> U64 mulMHashes = \x, y -> hash x * hash y - Id := U64 has [MHash {hash: hashId}] + Id := U64 implements [MHash {hash: hashId}] hashId = \@Id n -> n - Three := {} has [MHash {hash: hashThree}] + Three := {} implements [MHash {hash: hashThree}] hashThree = \@Three _ -> 3 result = mulMHashes (@Id 100) (@Three {}) @@ -9156,7 +9156,7 @@ In roc, functions are always written as a lambda, like{} Default has default : {} -> a | a implements Default main = - A := {} has [Default {default}] + A := {} implements [Default {default}] default = \{} -> @A {} default {} "# @@ -9406,7 +9406,7 @@ In roc, functions are always written as a lambda, like{} MEq has eq : a, a -> U64 | a implements MEq - A := U8 has [MEq {eq}] + A := U8 implements [MEq {eq}] "# ), @r###" @@ -9414,8 +9414,8 @@ In roc, functions are always written as a lambda, like{} An implementation of `eq` could not be found in this scope: - 5│ A := U8 has [MEq {eq}] - ^^ + 5│ A := U8 implements [MEq {eq}] + ^^ Tip: consider adding a value of name `eq` in this scope, or using another variable that implements this ability member, like @@ -9425,8 +9425,8 @@ In roc, functions are always written as a lambda, like{} This type does not fully implement the `MEq` ability: - 5│ A := U8 has [MEq {eq}] - ^^^^^^^^ + 5│ A := U8 implements [MEq {eq}] + ^^^^^^^^ The following necessary members are missing implementations: @@ -9442,7 +9442,7 @@ In roc, functions are always written as a lambda, like{} MEq has eq : a, a -> Bool | a implements MEq - A := U8 has [ MEq {eq: aMEq} ] + A := U8 implements [ MEq {eq: aMEq} ] myMEq = \m, n -> m == n "# @@ -9452,8 +9452,8 @@ In roc, functions are always written as a lambda, like{} Nothing is named `aMEq` in this scope. - 5│ A := U8 has [ MEq {eq: aMEq} ] - ^^^^ + 5│ A := U8 implements [ MEq {eq: aMEq} ] + ^^^^ Did you mean one of these? @@ -9466,8 +9466,8 @@ In roc, functions are always written as a lambda, like{} This type does not fully implement the `MEq` ability: - 5│ A := U8 has [ MEq {eq: aMEq} ] - ^^^^^^^^^^^^^^ + 5│ A := U8 implements [ MEq {eq: aMEq} ] + ^^^^^^^^^^^^^^ The following necessary members are missing implementations: @@ -9483,7 +9483,7 @@ In roc, functions are always written as a lambda, like{} MEq has eq : a, a -> Bool | a implements MEq - A := U8 has [ MEq {eq ? aMEq} ] + A := U8 implements [ MEq {eq ? aMEq} ] myMEq = \m, n -> m == n "# @@ -9493,8 +9493,8 @@ In roc, functions are always written as a lambda, like{} Ability implementations cannot be optional: - 5│ A := U8 has [ MEq {eq ? aMEq} ] - ^^^^^^^^^ + 5│ A := U8 implements [ MEq {eq ? aMEq} ] + ^^^^^^^^^ Custom implementations must be supplied fully. @@ -9504,8 +9504,8 @@ In roc, functions are always written as a lambda, like{} This type does not fully implement the `MEq` ability: - 5│ A := U8 has [ MEq {eq ? aMEq} ] - ^^^^^^^^^^^^^^^ + 5│ A := U8 implements [ MEq {eq ? aMEq} ] + ^^^^^^^^^^^^^^^ The following necessary members are missing implementations: @@ -9521,7 +9521,7 @@ In roc, functions are always written as a lambda, like{} imports [] provides [A, myEncoder] to "./platform" - A := U8 has [ Encoding {toEncoder ? myEncoder} ] + A := U8 implements [ Encoding {toEncoder ? myEncoder} ] myEncoder = 1 "# @@ -9531,21 +9531,21 @@ In roc, functions are always written as a lambda, like{} Ability implementations cannot be optional: - 5│ A := U8 has [ Encoding {toEncoder ? myEncoder} ] - ^^^^^^^^^^^^^^^^^^^^^ + 5│ A := U8 implements [ Encoding {toEncoder ? myEncoder} ] + ^^^^^^^^^^^^^^^^^^^^^ Custom implementations must be supplied fully. Hint: if you want this implementation to be derived, don't include a - record of implementations. For example, has [Encoding] will attempt + record of implementations. For example, implements [Encoding] will attempt to derive `Encoding` ── INCOMPLETE ABILITY IMPLEMENTATION ───────────────────── /code/proj/Main.roc ─ This type does not fully implement the `Encoding` ability: - 5│ A := U8 has [ Encoding {toEncoder ? myEncoder} ] - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 5│ A := U8 implements [ Encoding {toEncoder ? myEncoder} ] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following necessary members are missing implementations: @@ -9561,7 +9561,7 @@ In roc, functions are always written as a lambda, like{} MEq has eq : a, a -> Bool | a implements MEq - A := U8 has [ MEq {eq : Bool.eq} ] + A := U8 implements [ MEq {eq : Bool.eq} ] "# ), @r###" @@ -9569,8 +9569,8 @@ In roc, functions are always written as a lambda, like{} This ability implementation is qualified: - 5│ A := U8 has [ MEq {eq : Bool.eq} ] - ^^^^^^^ + 5│ A := U8 implements [ MEq {eq : Bool.eq} ] + ^^^^^^^ Custom implementations must be defined in the local scope, and unqualified. @@ -9579,8 +9579,8 @@ In roc, functions are always written as a lambda, like{} This type does not fully implement the `MEq` ability: - 5│ A := U8 has [ MEq {eq : Bool.eq} ] - ^^^^^^^^^^^^^^^^^^ + 5│ A := U8 implements [ MEq {eq : Bool.eq} ] + ^^^^^^^^^^^^^^^^^^ The following necessary members are missing implementations: @@ -9596,7 +9596,7 @@ In roc, functions are always written as a lambda, like{} MEq has eq : a, a -> Bool | a implements MEq - A := U8 has [ MEq {eq : \m, n -> m == n} ] + A := U8 implements [ MEq {eq : \m, n -> m == n} ] "# ), @r###" @@ -9604,8 +9604,8 @@ In roc, functions are always written as a lambda, like{} This ability implementation is not an identifier: - 5│ A := U8 has [ MEq {eq : \m, n -> m == n} ] - ^^^^^^^^^^^^^^^ + 5│ A := U8 implements [ MEq {eq : \m, n -> m == n} ] + ^^^^^^^^^^^^^^^ Custom ability implementations defined in this position can only be unqualified identifiers, not arbitrary expressions. @@ -9616,8 +9616,8 @@ In roc, functions are always written as a lambda, like{} This type does not fully implement the `MEq` ability: - 5│ A := U8 has [ MEq {eq : \m, n -> m == n} ] - ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 5│ A := U8 implements [ MEq {eq : \m, n -> m == n} ] + ^^^^^^^^^^^^^^^^^^^^^^^^^^ The following necessary members are missing implementations: @@ -9633,7 +9633,7 @@ In roc, functions are always written as a lambda, like{} MEq has eq : a, a -> Bool | a implements MEq - A := U8 has [ MEq {eq: eqA, eq: eqA} ] + A := U8 implements [ MEq {eq: eqA, eq: eqA} ] eqA = \@A m, @A n -> m == n "# @@ -9643,13 +9643,13 @@ In roc, functions are always written as a lambda, like{} This ability member implementation is duplicate: - 5│ A := U8 has [ MEq {eq: eqA, eq: eqA} ] - ^^^^^^^ + 5│ A := U8 implements [ MEq {eq: eqA, eq: eqA} ] + ^^^^^^^ The first implementation was defined here: - 5│ A := U8 has [ MEq {eq: eqA, eq: eqA} ] - ^^^^^^^ + 5│ A := U8 implements [ MEq {eq: eqA, eq: eqA} ] + ^^^^^^^ Only one custom implementation can be defined for an ability member. "### @@ -9663,7 +9663,7 @@ In roc, functions are always written as a lambda, like{} Foo := {} - A := U8 has [ Foo {} ] + A := U8 implements [ Foo {} ] "# ), @r###" @@ -9671,8 +9671,8 @@ In roc, functions are always written as a lambda, like{} This identifier is not an ability in scope: - 5│ A := U8 has [ Foo {} ] - ^^^ + 5│ A := U8 implements [ Foo {} ] + ^^^ Only abilities can be implemented. "### @@ -9686,7 +9686,7 @@ In roc, functions are always written as a lambda, like{} Ab has ab : a -> a | a implements Ab - A := {} has [Ab] + A := {} implements [Ab] "# ), @r###" @@ -9694,8 +9694,8 @@ In roc, functions are always written as a lambda, like{} This ability cannot be derived: - 5│ A := {} has [Ab] - ^^ + 5│ A := {} implements [Ab] + ^^ Only builtin abilities can be derived. @@ -9709,7 +9709,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" imports [] provides [A] to "./platform" - A a := a -> a has [Encode.Encoding] + A a := a -> a implements [Encode.Encoding] "# ), @r###" @@ -9717,8 +9717,8 @@ In roc, functions are always written as a lambda, like{} I can't derive an implementation of the `Encoding` ability for `A`: - 3│ A a := a -> a has [Encode.Encoding] - ^^^^^^^^^^^^^^^ + 3│ A a := a -> a implements [Encode.Encoding] + ^^^^^^^^^^^^^^^ Note: `Encoding` cannot be generated for functions. @@ -9732,7 +9732,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" imports [] provides [A] to "./platform" - A := B has [Encode.Encoding] + A := B implements [Encode.Encoding] B := {} "# @@ -9742,8 +9742,8 @@ In roc, functions are always written as a lambda, like{} I can't derive an implementation of the `Encoding` ability for `A`: - 3│ A := B has [Encode.Encoding] - ^^^^^^^^^^^^^^^ + 3│ A := B implements [Encode.Encoding] + ^^^^^^^^^^^^^^^ Tip: `B` does not implement `Encoding`. Consider adding a custom implementation or `has Encode.Encoding` to the definition of `B`. @@ -9758,9 +9758,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" imports [] provides [A] to "./platform" - A := B has [Encode.Encoding] + A := B implements [Encode.Encoding] - B := {} has [Encode.Encoding] + B := {} implements [Encode.Encoding] "# ), @"" // no error @@ -9772,7 +9772,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" imports [] provides [MyNat] to "./platform" - MyNat := [S MyNat, Z] has [Encode.Encoding] + MyNat := [S MyNat, Z] implements [Encode.Encoding] "# ), @"" // no error @@ -10501,9 +10501,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [hash, Id, Id2] to "./platform" - MHash has hash : a -> U64 | a implements MHash + MHash implements hash : a -> U64 | a implements MHash - Id := {} has [MHash {hash}] + Id := {} implements [MHash {hash}] Id2 := {} hash = \@Id2 _ -> 0 @@ -10581,7 +10581,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" imports [] provides [A] to "./platform" - A a := a -> a has [Decode.Decoding] + A a := a -> a implements [Decode.Decoding] "# ), @r###" @@ -10589,8 +10589,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Decoding` ability for `A`: - 3│ A a := a -> a has [Decode.Decoding] - ^^^^^^^^^^^^^^^ + 3│ A a := a -> a implements [Decode.Decoding] + ^^^^^^^^^^^^^^^ Note: `Decoding` cannot be generated for functions. @@ -10604,7 +10604,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" imports [] provides [A] to "./platform" - A := B has [Decode.Decoding] + A := B implements [Decode.Decoding] B := {} "# @@ -10614,8 +10614,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Decoding` ability for `A`: - 3│ A := B has [Decode.Decoding] - ^^^^^^^^^^^^^^^ + 3│ A := B implements [Decode.Decoding] + ^^^^^^^^^^^^^^^ Tip: `B` does not implement `Decoding`. Consider adding a custom implementation or `has Decode.Decoding` to the definition of `B`. @@ -10630,9 +10630,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" imports [] provides [A] to "./platform" - A := B has [Decode.Decoding] + A := B implements [Decode.Decoding] - B := {} has [Decode.Decoding] + B := {} implements [Decode.Decoding] "# ), @"" // no error @@ -10644,7 +10644,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" imports [] provides [MyNat] to "./platform" - MyNat := [S MyNat, Z] has [Decode.Decoding] + MyNat := [S MyNat, Z] implements [Decode.Decoding] "# ), @"" // no error @@ -11245,7 +11245,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A a := a -> a has [Hash] + A a := a -> a implements [Hash] "# ), @r###" @@ -11253,8 +11253,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Hash` ability for `A`: - 3│ A a := a -> a has [Hash] - ^^^^ + 3│ A a := a -> a implements [Hash] + ^^^^ Note: `Hash` cannot be generated for functions. @@ -11268,7 +11268,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A := B has [Hash] + A := B implements [Hash] B := {} "# @@ -11278,8 +11278,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Hash` ability for `A`: - 3│ A := B has [Hash] - ^^^^ + 3│ A := B implements [Hash] + ^^^^ Tip: `B` does not implement `Hash`. Consider adding a custom implementation or `has Hash.Hash` to the definition of `B`. @@ -11294,9 +11294,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A := B has [Hash] + A := B implements [Hash] - B := {} has [Hash] + B := {} implements [Hash] "# ), @"" // no error @@ -11308,7 +11308,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [MyNat] to "./platform" - MyNat := [S MyNat, Z] has [Hash] + MyNat := [S MyNat, Z] implements [Hash] "# ), @"" // no error @@ -11546,7 +11546,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A a := a -> a has [Eq] + A a := a -> a implements [Eq] "# ), @r###" @@ -11554,8 +11554,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Eq` ability for `A`: - 3│ A a := a -> a has [Eq] - ^^ + 3│ A a := a -> a implements [Eq] + ^^ Note: `Eq` cannot be generated for functions. @@ -11601,7 +11601,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A := F32 has [Eq] + A := F32 implements [Eq] "# ), @r###" @@ -11609,8 +11609,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Eq` ability for `A`: - 3│ A := F32 has [Eq] - ^^ + 3│ A := F32 implements [Eq] + ^^ Note: I can't derive `Bool.isEq` for floating-point types. That's because Roc's floating-point numbers cannot be compared for total @@ -11627,7 +11627,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A := F64 has [Eq] + A := F64 implements [Eq] "# ), @r###" @@ -11635,8 +11635,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Eq` ability for `A`: - 3│ A := F64 has [Eq] - ^^ + 3│ A := F64 implements [Eq] + ^^ Note: I can't derive `Bool.isEq` for floating-point types. That's because Roc's floating-point numbers cannot be compared for total @@ -11653,7 +11653,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A := B has [Eq] + A := B implements [Eq] B := {} "# @@ -11663,8 +11663,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Eq` ability for `A`: - 3│ A := B has [Eq] - ^^ + 3│ A := B implements [Eq] + ^^ Tip: `B` does not implement `Eq`. Consider adding a custom implementation or `has Bool.Eq` to the definition of `B`. @@ -11679,9 +11679,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [A] to "./platform" - A := B has [Eq] + A := B implements [Eq] - B := {} has [Eq] + B := {} implements [Eq] "# ), @"" // no error @@ -11693,7 +11693,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [MyNat] to "./platform" - MyNat := [S MyNat, Z] has [Eq] + MyNat := [S MyNat, Z] implements [Eq] "# ), @"" // no error @@ -11988,7 +11988,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - F := U8 -> U8 has [Hash, Eq, Encoding] + F := U8 -> U8 implements [Hash, Eq, Encoding] main = "" "# @@ -11998,8 +11998,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Hash` ability for `F`: - 3│ F := U8 -> U8 has [Hash, Eq, Encoding] - ^^^^ + 3│ F := U8 -> U8 implements [Hash, Eq, Encoding] + ^^^^ Note: `Hash` cannot be generated for functions. @@ -12009,8 +12009,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Eq` ability for `F`: - 3│ F := U8 -> U8 has [Hash, Eq, Encoding] - ^^ + 3│ F := U8 -> U8 implements [Hash, Eq, Encoding] + ^^ Note: `Eq` cannot be generated for functions. @@ -12020,8 +12020,8 @@ I recommend using camelCase. It's the standard style in Roc code! I can't derive an implementation of the `Encoding` ability for `F`: - 3│ F := U8 -> U8 has [Hash, Eq, Encoding] - ^^^^^^^^ + 3│ F := U8 -> U8 implements [Hash, Eq, Encoding] + ^^^^^^^^ Note: `Encoding` cannot be generated for functions. From 2f5695e59d0602c97ebef2a66a001b40349a460f Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Mon, 22 May 2023 22:29:32 -0400 Subject: [PATCH 20/55] use `word` instead of `word10` --- crates/compiler/parse/src/parser.rs | 59 ++++++-------------- crates/compiler/parse/src/type_annotation.rs | 30 +--------- 2 files changed, 20 insertions(+), 69 deletions(-) diff --git a/crates/compiler/parse/src/parser.rs b/crates/compiler/parse/src/parser.rs index ec6b6186064..26048884176 100644 --- a/crates/compiler/parse/src/parser.rs +++ b/crates/compiler/parse/src/parser.rs @@ -1524,6 +1524,23 @@ where } } +pub fn word<'a, ToError, E>(word: &'static str, to_error: ToError) -> impl Parser<'a, (), E> +where + ToError: Fn(Position) -> E, + E: 'a, +{ + debug_assert!(!word.contains('\n')); + + move |_arena: &'a Bump, state: State<'a>, _min_indent: u32| { + if state.bytes().starts_with(word.as_bytes()) { + let state = state.advance(word.len()); + Ok((MadeProgress, (), state)) + } else { + Err((NoProgress, to_error(state.pos()))) + } + } +} + pub fn word1<'a, ToError, E>(word: u8, to_error: ToError) -> impl Parser<'a, (), E> where ToError: Fn(Position) -> E, @@ -1608,48 +1625,6 @@ where } } -pub fn word10<'a, ToError, E>( - word_1: u8, - word_2: u8, - word_3: u8, - word_4: u8, - word_5: u8, - word_6: u8, - word_7: u8, - word_8: u8, - word_9: u8, - word_10: u8, - to_error: ToError, -) -> impl Parser<'a, (), E> -where - ToError: Fn(Position) -> E, - E: 'a, -{ - debug_assert_ne!(word_1, b'\n'); - debug_assert_ne!(word_2, b'\n'); - debug_assert_ne!(word_3, b'\n'); - debug_assert_ne!(word_4, b'\n'); - debug_assert_ne!(word_5, b'\n'); - debug_assert_ne!(word_6, b'\n'); - debug_assert_ne!(word_7, b'\n'); - debug_assert_ne!(word_8, b'\n'); - debug_assert_ne!(word_9, b'\n'); - debug_assert_ne!(word_10, b'\n'); - - let needle = [ - word_1, word_2, word_3, word_4, word_5, word_6, word_7, word_8, word_9, word_10, - ]; - - move |_arena: &'a Bump, state: State<'a>, _min_indent: u32| { - if state.bytes().starts_with(&needle) { - let state = state.advance(10); - Ok((MadeProgress, (), state)) - } else { - Err((NoProgress, to_error(state.pos()))) - } - } -} - #[macro_export] macro_rules! word1_check_indent { ($word:expr, $word_problem:expr, $min_indent:expr, $indent_problem:expr) => { diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 92ec2404c12..a45bd3699ad 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -12,7 +12,7 @@ use crate::parser::{ absolute_column_min_indent, increment_min_indent, then, ERecord, ETypeAbilityImpl, }; use crate::parser::{ - allocated, backtrackable, fail, optional, specialize, specialize_ref, word1, word10, word2, + allocated, backtrackable, fail, optional, specialize, specialize_ref, word, word1, word2, EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser, Progress::{self, *}, }; @@ -459,19 +459,7 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<' ), skip_first!( // Parse "implements"; we don't care about this keyword - word10( - b'i', - b'm', - b'p', - b'l', - b'e', - b'm', - b'e', - b'n', - b't', - b's', - EType::THasClause - ), + word("implements", EType::THasClause), // Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash" absolute_column_min_indent(ability_chain()) ) @@ -524,19 +512,7 @@ fn implements_clause_chain<'a>( pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { increment_min_indent(skip_first!( // Parse "implements"; we don't care about this keyword - word10( - b'i', - b'm', - b'p', - b'l', - b'e', - b'm', - b'e', - b'n', - b't', - b's', - EType::THasClause - ), + word("implements", EType::THasClause), // Parse "Hash"; this may be qualified from another module like "Hash.Hash" space0_before_e( loc!(map!( From 57c01de7922d144103f6de47d4ad2a408e03f6eb Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 10:36:18 -0400 Subject: [PATCH 21/55] `has [...]` -> `implements [...]` --- crates/compiler/builtins/roc/Bool.roc | 2 +- crates/compiler/builtins/roc/Decode.roc | 4 ++-- crates/compiler/builtins/roc/Encode.roc | 4 ++-- crates/compiler/builtins/roc/Hash.roc | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/compiler/builtins/roc/Bool.roc b/crates/compiler/builtins/roc/Bool.roc index 1dbaef12289..37eea3dff22 100644 --- a/crates/compiler/builtins/roc/Bool.roc +++ b/crates/compiler/builtins/roc/Bool.roc @@ -12,7 +12,7 @@ interface Bool ## be a `NaN` ([Not a Number](https://en.wikipedia.org/wiki/NaN)), and the ## [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754) floating point standard ## specifies that two `NaN`s are not equal. -Eq has +Eq implements ## Returns `Bool.true` if the input values are equal. This is ## equivalent to the logic ## [XNOR](https://en.wikipedia.org/wiki/Logical_equality) gate. The infix diff --git a/crates/compiler/builtins/roc/Decode.roc b/crates/compiler/builtins/roc/Decode.roc index 850b71de30a..96b17ac237a 100644 --- a/crates/compiler/builtins/roc/Decode.roc +++ b/crates/compiler/builtins/roc/Decode.roc @@ -76,11 +76,11 @@ DecodeResult val : { result : Result val DecodeError, rest : List U8 } Decoder val fmt := List U8, fmt -> DecodeResult val | fmt implements DecoderFormatting ## Definition of the [Decoding] ability -Decoding has +Decoding implements decoder : Decoder val fmt | val implements Decoding, fmt implements DecoderFormatting ## Definition of the [DecoderFormatting] ability -DecoderFormatting has +DecoderFormatting implements u8 : Decoder U8 fmt | fmt implements DecoderFormatting u16 : Decoder U16 fmt | fmt implements DecoderFormatting u32 : Decoder U32 fmt | fmt implements DecoderFormatting diff --git a/crates/compiler/builtins/roc/Encode.roc b/crates/compiler/builtins/roc/Encode.roc index 26ba2f77cc9..b20e22428ac 100644 --- a/crates/compiler/builtins/roc/Encode.roc +++ b/crates/compiler/builtins/roc/Encode.roc @@ -49,10 +49,10 @@ interface Encode Encoder fmt := List U8, fmt -> List U8 | fmt implements EncoderFormatting -Encoding has +Encoding implements toEncoder : val -> Encoder fmt | val implements Encoding, fmt implements EncoderFormatting -EncoderFormatting has +EncoderFormatting implements u8 : U8 -> Encoder fmt | fmt implements EncoderFormatting u16 : U16 -> Encoder fmt | fmt implements EncoderFormatting u32 : U32 -> Encoder fmt | fmt implements EncoderFormatting diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index da6b9dda1c3..5e54571af8b 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -28,7 +28,7 @@ interface Hash ] ## A value that can hashed. -Hash has +Hash implements ## Hashes a value into a [Hasher]. ## Note that [hash] does not produce a hash value itself; the hasher must be ## [complete]d in order to extract the hash value. @@ -39,7 +39,7 @@ Hash has ## The [Hasher] ability describes general-purpose hashers. It only allows ## emission of 64-bit unsigned integer hashes. It is not suitable for ## cryptographically-secure hashing. -Hasher has +Hasher implemenets ## Adds a list of bytes to the hasher. addBytes : a, List U8 -> a | a implements Hasher From b05befd770cb8eb97186a75eddf78e7da6b1b094 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 10:38:06 -0400 Subject: [PATCH 22/55] `ident: "has"` -> `ident: "implements"` --- crates/compiler/parse/src/expr.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 7e5cf1a5273..2e787bdc344 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1286,7 +1286,7 @@ mod ability { Exact(u32), } - /// Parses an ability demand like `hash : a -> U64 | a has Hash`, in the context of a larger + /// Parses an ability demand like `hash : a -> U64 | a implements Hash`, in the context of a larger /// ability definition. /// This is basically the same as parsing a free-floating annotation, but with stricter rules. pub fn parse_demand<'a>( @@ -1641,13 +1641,13 @@ fn parse_expr_end<'a>( value: Expr::Var { module_name: "", - ident: "has", + ident: "implements", }, .. }, state, )) if matches!(expr_state.expr.value, Expr::Tag(..)) => { - // This is an ability definition, `Ability arg1 ... has ...`. + // This is an ability definition, `Ability arg1 ... implements ...`. let name = expr_state.expr.map_owned(|e| match e { Expr::Tag(name) => name, @@ -1668,7 +1668,7 @@ fn parse_expr_end<'a>( } } - // Attach any spaces to the `has` keyword + // Attach any spaces to the `implements` keyword let has = if !expr_state.spaces_after.is_empty() { arena .alloc(Implements::Implements) From abb48e9d5e7d5a032e11e5410d459452eb6cb7e6 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 10:38:52 -0400 Subject: [PATCH 23/55] `Identifier("has")` -> `Identifier("implements")` --- crates/compiler/parse/src/pattern.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index b35dac7e5d1..96c3b3c7201 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -116,7 +116,7 @@ fn loc_tag_pattern_args_help<'a>() -> impl Parser<'a, Vec<'a, Loc>>, zero_or_more!(loc_tag_pattern_arg(false)) } -/// Like `loc_tag_pattern_args_help`, but stops if a "has" keyword is seen (indicating an ability). +/// Like `loc_tag_pattern_args_help`, but stops if a "implements" keyword is seen (indicating an ability). fn loc_type_def_tag_pattern_args_help<'a>( ) -> impl Parser<'a, Vec<'a, Loc>>, EPattern<'a>> { zero_or_more!(loc_tag_pattern_arg(true)) @@ -138,7 +138,7 @@ fn loc_tag_pattern_arg<'a>( let Loc { region, value } = loc_pat; - if stop_on_has_kw && matches!(value, Pattern::Identifier("has")) { + if stop_on_has_kw && matches!(value, Pattern::Identifier("implements")) { Err((NoProgress, EPattern::End(original_state.pos()))) } else { Ok(( @@ -158,7 +158,7 @@ pub fn loc_has_parser<'a>() -> impl Parser<'a, Loc>, EPattern<'a> then( loc_tag_pattern_arg(false), |_arena, state, progress, pattern| { - if matches!(pattern.value, Pattern::Identifier("has")) { + if matches!(pattern.value, Pattern::Identifier("implements")) { Ok(( progress, Loc::at(pattern.region, Implements::Implements), From 34026833b1ec65a94997d2e0f7342efc7b7f9f59 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 10:39:48 -0400 Subject: [PATCH 24/55] "has" -> "implements" --- crates/compiler/parse/src/type_annotation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index a45bd3699ad..2de4dbde4be 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -726,7 +726,7 @@ fn parse_type_variable<'a>( min_indent, ) { Ok((_, name, state)) => { - if name == "has" && stop_at_surface_has { + if name == "implements" && stop_at_surface_has { Err((NoProgress, EType::TEnd(state.pos()))) } else { let answer = TypeAnnotation::BoundVariable(name); From 55bb8f4b6cc9658ba1c544824de039c92f9e85a0 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 10:53:13 -0400 Subject: [PATCH 25/55] fix typo --- crates/compiler/builtins/roc/Hash.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index 5e54571af8b..490f3e6f4ca 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -39,7 +39,7 @@ Hash implements ## The [Hasher] ability describes general-purpose hashers. It only allows ## emission of 64-bit unsigned integer hashes. It is not suitable for ## cryptographically-secure hashing. -Hasher implemenets +Hasher implements ## Adds a list of bytes to the hasher. addBytes : a, List U8 -> a | a implements Hasher From 91e37293a28327eba710f8ce704431828d6a1977 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 21:29:38 -0400 Subject: [PATCH 26/55] abilities syntax `has` -> `implements` --- crates/cli/tests/cli_run.rs | 1 + .../build/interface_with_deps/AStar.roc | 12 +- .../compiler/load_internal/tests/test_load.rs | 12 +- crates/compiler/solve/tests/solve_expr.rs | 6 +- crates/compiler/test_derive/src/decoding.rs | 12 +- crates/compiler/test_derive/src/encoding.rs | 54 +++---- crates/compiler/test_derive/src/hash.rs | 40 +++--- crates/compiler/test_gen/src/gen_abilities.rs | 134 +++++++++--------- crates/compiler/test_gen/src/gen_list.rs | 4 +- crates/compiler/test_gen/src/gen_num.rs | 2 +- crates/compiler/test_mono/src/tests.rs | 44 +++--- crates/compiler/test_syntax/fuzz/dict.txt | 2 +- .../ability_demand_value_has_args.expr.roc | 4 +- ...y_demands_not_indented_with_first.expr.roc | 6 +- ..._first_demand_not_indented_enough.expr.roc | 4 +- .../ability_non_signature_expression.expr.roc | 2 +- ..._signature_is_multiline.expr.formatted.roc | 2 +- ...ity_demand_signature_is_multiline.expr.roc | 2 +- .../ability_multi_line.expr.formatted.roc | 2 +- .../pass/ability_multi_line.expr.roc | 2 +- .../pass/ability_single_line.expr.roc | 2 +- .../pass/ability_two_in_a_row.expr.roc | 4 +- .../opaque_has_abilities.expr.formatted.roc | 26 ++-- .../pass/opaque_has_abilities.expr.roc | 24 ++-- .../pass/where_clause_function.expr.roc | 2 +- ...ultiple_bound_abilities.expr.formatted.roc | 4 +- ...e_clause_multiple_bound_abilities.expr.roc | 6 +- .../pass/where_clause_multiple_has.expr.roc | 2 +- ...ple_has_across_newlines.expr.formatted.roc | 2 +- ...ause_multiple_has_across_newlines.expr.roc | 6 +- .../pass/where_clause_non_function.expr.roc | 2 +- ...where_clause_on_newline.expr.formatted.roc | 2 +- .../pass/where_clause_on_newline.expr.roc | 2 +- crates/compiler/test_syntax/tests/test_fmt.rs | 54 +++---- .../expand_able_variables_in_type_alias.txt | 4 +- ...bles_bound_to_an_ability_from_type_def.txt | 4 +- ...s_are_superset_of_flex_bounds_admitted.txt | 8 +- ...e_variable_bound_to_ability_issue_4408.txt | 4 +- ...pl_ability_for_opaque_with_lambda_sets.txt | 2 +- ...y_for_opaque_with_lambda_sets_material.txt | 2 +- .../uitest/tests/ability/smoke/decoder.txt | 16 +-- .../uitest/tests/ability/smoke/encoder.txt | 16 +-- .../tests/ability/specialize/bool_decoder.txt | 2 +- .../tests/ability/specialize/bool_hash.txt | 2 +- .../ability/specialize/bool_to_encoder.txt | 2 +- .../specialize/opaque_decoder_derive.txt | 4 +- .../specialize/opaque_encoder_derive.txt | 4 +- .../ability/specialize/opaque_eq_custom.txt | 2 +- .../ability/specialize/opaque_eq_derive.txt | 2 +- .../ability/specialize/opaque_hash_custom.txt | 4 +- .../ability/specialize/opaque_hash_derive.txt | 4 +- .../polymorphic_lambda_set_specialization.txt | 10 +- ...lambda_set_specialization_bound_output.txt | 10 +- ...ization_branching_over_single_variable.txt | 14 +- ...zation_varying_over_multiple_variables.txt | 26 ++-- ...ng_over_multiple_variables_two_results.txt | 32 ++--- ...n_with_deep_specialization_and_capture.txt | 10 +- ...a_set_specialization_with_let_weakened.txt | 10 +- ...ialization_with_let_weakened_unapplied.txt | 16 +-- .../ability/specialize/ranged_num_hash.txt | 2 +- .../ability/specialize/record_to_encoder.txt | 2 +- ...ord_to_encoder_with_nested_custom_impl.txt | 4 +- .../resolve_lambda_set_ability_chain.txt | 6 +- ...da_set_branches_ability_vs_non_ability.txt | 4 +- ...solve_lambda_set_branches_same_ability.txt | 4 +- ...e_lambda_set_generalized_ability_alias.txt | 8 +- ...olve_lambda_set_weakened_ability_alias.txt | 4 +- ...mutually_recursive_ability_lambda_sets.txt | 6 +- ...recursive_ability_lambda_sets_inferred.txt | 6 +- .../resolve_recursive_ability_lambda_set.txt | 4 +- ...cialized_lambda_sets_in_one_lambda_set.txt | 4 +- ..._unspecialized_lambda_set_behind_alias.txt | 6 +- ...unspecialized_lambda_set_behind_opaque.txt | 4 +- .../specialize/static_specialization.txt | 4 +- .../call_generic_ability_member.txt | 10 +- ...ed_specialization_with_annotation_only.txt | 6 +- ...checked_specialization_with_typed_body.txt | 6 +- ...bility_constrained_in_non_member_check.txt | 8 +- ...bility_constrained_in_non_member_infer.txt | 6 +- ..._constrained_in_non_member_infer_usage.txt | 6 +- ...in_non_member_multiple_specializations.txt | 8 +- .../solve/ability_specialization_called.txt | 6 +- .../tests/solve/alias_ability_member.txt | 6 +- .../tests/solve/alias_propagates_able_var.txt | 6 +- .../tests/solve/exposed_ability_name.txt | 4 +- ...ities_multiple_members_specializations.txt | 14 +- ...ility_multiple_members_specializations.txt | 8 +- ..._ability_single_member_specializations.txt | 4 +- .../uitest/tests/solve/stdlib_encode_json.txt | 2 +- crates/reporting/tests/test_reporting.rs | 12 +- 90 files changed, 438 insertions(+), 437 deletions(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 21a17eda785..60729b4b10b 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -634,6 +634,7 @@ mod cli_run { } #[test] + #[ignore] #[cfg_attr( windows, ignore = "this platform is broken, and `roc run --lib` is missing on windows" diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc b/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc index 6cfa12bbb8a..155d9ec8045 100644 --- a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc +++ b/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc @@ -13,7 +13,7 @@ Model position : } -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 @@ -22,7 +22,7 @@ initialModel = \start -> } -cheapestOpen : (position -> F64), Model position -> Result position [KeyNotFound] | position has Hash & Eq +cheapestOpen : (position -> F64), Model position -> Result position [KeyNotFound] | position implements Hash & Eq cheapestOpen = \costFunction, model -> folder = \resSmallestSoFar, position -> @@ -47,7 +47,7 @@ cheapestOpen = \costFunction, model -> -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 KeyNotFound -> @@ -56,7 +56,7 @@ reconstructPath = \cameFrom, goal -> 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, neighbour, model -> newCameFrom = Dict.insert model.cameFrom neighbour current @@ -80,12 +80,12 @@ updateCost = \current, neighbour, model -> model -findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [KeyNotFound] | position has Hash & Eq +findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [KeyNotFound] | position implements Hash & Eq findPath = \{ costFunction, moveFunction, start, end } -> astar costFunction moveFunction end (initialModel start) -astar : (position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] | position has Hash & Eq +astar : (position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] | position implements Hash & Eq astar = \costFn, moveFn, goal, model -> when cheapestOpen (\position -> costFn goal position) model is Err _ -> diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index b16990c61a6..7aa625372db 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -491,12 +491,12 @@ fn load_astar() { expect_types( loaded_module, hashmap! { - "findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [KeyNotFound] | position has Hash & Eq", - "initialModel" => "position -> Model position | position has Hash & Eq", - "reconstructPath" => "Dict position position, position -> List position | position has Hash & Eq", - "updateCost" => "position, position, Model position -> Model position | position has Hash & Eq", - "cheapestOpen" => "(position -> F64), Model position -> Result position [KeyNotFound] | position has Hash & Eq", - "astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] | position has Hash & Eq", + "findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [KeyNotFound] | position implements Hash & Eq", + "initialModel" => "position -> Model position | position implements Hash & Eq", + "reconstructPath" => "Dict position position, position -> List position | position implements Hash & Eq", + "updateCost" => "position, position, Model position -> Model position | position implements Hash & Eq", + "cheapestOpen" => "(position -> F64), Model position -> Result position [KeyNotFound] | position implements Hash & Eq", + "astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] | position implements Hash & Eq", }, ); } diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 584d7f10368..444b7b59bcd 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -3150,7 +3150,7 @@ mod solve_expr { Dict.insert "# ), - "Dict k v, k, v -> Dict k v | k has Hash & Eq", + "Dict k v, k, v -> Dict k v | k implements Hash & Eq", ); } @@ -3423,7 +3423,7 @@ mod solve_expr { reconstructPath "# ), - "Dict position position, position -> List position | position has Hash & Eq", + "Dict position position, position -> List position | position implements Hash & Eq", ); } @@ -3480,7 +3480,7 @@ mod solve_expr { astar "# ), - "Model position -> Result position [KeyNotFound] | position has Hash & Eq", + "Model position -> Result position [KeyNotFound] | position implements Hash & Eq", ); } diff --git a/crates/compiler/test_derive/src/decoding.rs b/crates/compiler/test_derive/src/decoding.rs index 14fe23abd1f..de6695380a1 100644 --- a/crates/compiler/test_derive/src/decoding.rs +++ b/crates/compiler/test_derive/src/decoding.rs @@ -106,8 +106,8 @@ fn list() { derive_test(Decoder, v!(Symbol::LIST_LIST v!(STR)), |golden| { assert_snapshot!(golden, @r###" # derived for List Str - # Decoder (List val) fmt | fmt has DecoderFormatting, val has Decoding - # List U8, fmt -[[custom(3)]]-> { rest : List U8, result : [Err [TooShort], Ok (List val)] } | fmt has DecoderFormatting, val has Decoding + # Decoder (List val) fmt | fmt has DecoderFormatting, val implements Decoding + # List U8, fmt -[[custom(3)]]-> { rest : List U8, result : [Err [TooShort], Ok (List val)] } | fmt has DecoderFormatting, val implements Decoding # Specialization lambda sets: # @<1>: [[custom(3)]] #Derived.decoder_list = @@ -124,8 +124,8 @@ fn record_2_fields() { derive_test(Decoder, v!({first: v!(STR), second: v!(STR),}), |golden| { assert_snapshot!(golden, @r###" # derived for { first : Str, second : Str } - # Decoder { first : val, second : val1 } fmt | fmt has DecoderFormatting, val has Decoding, val1 has Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt has DecoderFormatting, val has Decoding, val1 has Decoding + # Decoder { first : val, second : val1 } fmt | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_{first,second} = @@ -181,8 +181,8 @@ fn tuple_2_fields() { derive_test(Decoder, v!((v!(STR), v!(U8),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( Str, U8 )* - # Decoder ( val, val1 )* fmt | fmt has DecoderFormatting, val has Decoding, val1 has Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt has DecoderFormatting, val has Decoding, val1 has Decoding + # Decoder ( val, val1 )* fmt | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_(arity:2) = diff --git a/crates/compiler/test_derive/src/encoding.rs b/crates/compiler/test_derive/src/encoding.rs index ab45eb77519..b726cd5930c 100644 --- a/crates/compiler/test_derive/src/encoding.rs +++ b/crates/compiler/test_derive/src/encoding.rs @@ -188,8 +188,8 @@ fn empty_record() { derive_test(ToEncoder, v!(EMPTY_RECORD), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # {} -[[toEncoder_{}(0)]]-> Encoder fmt | fmt has EncoderFormatting - # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) | fmt has EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> Encoder fmt | fmt implements EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) | fmt implements EncoderFormatting # Specialization lambda sets: # @<1>: [[toEncoder_{}(0)]] # @<2>: [[custom(2) {}]] @@ -208,8 +208,8 @@ fn zero_field_record() { derive_test(ToEncoder, v!({}), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # {} -[[toEncoder_{}(0)]]-> Encoder fmt | fmt has EncoderFormatting - # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) | fmt has EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> Encoder fmt | fmt implements EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) | fmt implements EncoderFormatting # Specialization lambda sets: # @<1>: [[toEncoder_{}(0)]] # @<2>: [[custom(2) {}]] @@ -228,11 +228,11 @@ fn one_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8 } - # { a : val } -[[toEncoder_{a}(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding - # { a : val } -[[toEncoder_{a}(0)]]-> (List U8, fmt -[[custom(2) { a : val }]]-> List U8) | fmt has EncoderFormatting, val has Encoding + # { a : val } -[[toEncoder_{a}(0)]]-> Encoder fmt | fmt has EncoderFormatting, val implements Encoding + # { a : val } -[[toEncoder_{a}(0)]]-> (List U8, fmt -[[custom(2) { a : val }]]-> List U8) | fmt has EncoderFormatting, val implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a}(0)]] - # @<2>: [[custom(2) { a : val }]] | val has Encoding + # @<2>: [[custom(2) { a : val }]] | val implements Encoding #Derived.toEncoder_{a} = \#Derived.rcd -> custom @@ -251,11 +251,11 @@ fn two_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 has Encoding - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 has Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a,b}(0)]] - # @<2>: [[custom(2) { a : val, b : val1 }]] | val has Encoding, val1 has Encoding + # @<2>: [[custom(2) { a : val, b : val1 }]] | val has Encoding, val1 implements Encoding #Derived.toEncoder_{a,b} = \#Derived.rcd -> custom @@ -278,11 +278,11 @@ fn two_field_tuple() { derive_test(ToEncoder, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 has Encoding - # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 has Encoding + # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_(arity:2)(0)]] - # @<2>: [[custom(2) ( val, val1 )*]] | val has Encoding, val1 has Encoding + # @<2>: [[custom(2) ( val, val1 )*]] | val has Encoding, val1 implements Encoding #Derived.toEncoder_(arity:2) = \#Derived.tup -> custom @@ -314,8 +314,8 @@ fn tag_one_label_zero_args() { derive_test(ToEncoder, v!([A]), |golden| { assert_snapshot!(golden, @r###" # derived for [A] - # [A] -[[toEncoder_[A 0](0)]]-> Encoder fmt | fmt has EncoderFormatting - # [A] -[[toEncoder_[A 0](0)]]-> (List U8, fmt -[[custom(2) [A]]]-> List U8) | fmt has EncoderFormatting + # [A] -[[toEncoder_[A 0](0)]]-> Encoder fmt | fmt implements EncoderFormatting + # [A] -[[toEncoder_[A 0](0)]]-> (List U8, fmt -[[custom(2) [A]]]-> List U8) | fmt implements EncoderFormatting # Specialization lambda sets: # @<1>: [[toEncoder_[A 0](0)]] # @<2>: [[custom(2) [A]]] @@ -338,11 +338,11 @@ fn tag_one_label_two_args() { derive_test(ToEncoder, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 has Encoding - # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 has Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 2](0)]] - # @<2>: [[custom(4) [A val val1]]] | val has Encoding, val1 has Encoding + # @<2>: [[custom(4) [A val val1]]] | val has Encoding, val1 implements Encoding #Derived.toEncoder_[A 2] = \#Derived.tag -> custom @@ -366,11 +366,11 @@ fn tag_two_labels() { |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 has Encoding - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 has Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 3,B 1](0)]] - # @<2>: [[custom(6) [A val val1 val1, B val1]]] | val has Encoding, val1 has Encoding + # @<2>: [[custom(6) [A val val1 val1, B val1]]] | val has Encoding, val1 implements Encoding #Derived.toEncoder_[A 3,B 1] = \#Derived.tag -> custom @@ -402,11 +402,11 @@ fn recursive_tag_union() { |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 has Encoding - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 has Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[Cons 2,Nil 0](0)]] - # @<2>: [[custom(4) [Cons val val1, Nil]]] | val has Encoding, val1 has Encoding + # @<2>: [[custom(4) [Cons val val1, Nil]]] | val has Encoding, val1 implements Encoding #Derived.toEncoder_[Cons 2,Nil 0] = \#Derived.tag -> custom @@ -429,11 +429,11 @@ fn list() { derive_test(ToEncoder, v!(Symbol::LIST_LIST v!(STR)), |golden| { assert_snapshot!(golden, @r###" # derived for List Str - # List val -[[toEncoder_list(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding - # List val -[[toEncoder_list(0)]]-> (List U8, fmt -[[custom(4) (List val)]]-> List U8) | fmt has EncoderFormatting, val has Encoding + # List val -[[toEncoder_list(0)]]-> Encoder fmt | fmt has EncoderFormatting, val implements Encoding + # List val -[[toEncoder_list(0)]]-> (List U8, fmt -[[custom(4) (List val)]]-> List U8) | fmt has EncoderFormatting, val implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_list(0)]] - # @<2>: [[custom(4) (List val)]] | val has Encoding + # @<2>: [[custom(4) (List val)]] | val implements Encoding #Derived.toEncoder_list = \#Derived.lst -> custom diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index 4847f1044e4..669fb37d25a 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -151,8 +151,8 @@ fn empty_record() { derive_test(Hash, v!(EMPTY_RECORD), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{}(0)]] #Derived.hash_{} = \#Derived.hasher, #Derived.rcd -> #Derived.hasher @@ -166,8 +166,8 @@ fn zero_field_record() { derive_test(Hash, v!({}), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{}(0)]] #Derived.hash_{} = \#Derived.hasher, #Derived.rcd -> #Derived.hasher @@ -181,8 +181,8 @@ fn one_field_record() { derive_test(Hash, v!({ a: v!(U8), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8 } - # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher has Hasher - # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher has Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher implements Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a}(0)]] #Derived.hash_{a} = @@ -197,8 +197,8 @@ fn two_field_record() { derive_test(Hash, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a,b}(0)]] #Derived.hash_{a,b} = @@ -214,8 +214,8 @@ fn two_element_tuple() { derive_test(Hash, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_(arity:2)(0)]] #Derived.hash_(arity:2) = @@ -231,8 +231,8 @@ fn tag_one_label_no_payloads() { derive_test(Hash, v!([A]), |golden| { assert_snapshot!(golden, @r###" # derived for [A] - # hasher, [A] -[[hash_[A 0](0)]]-> hasher | hasher has Hasher - # hasher, [A] -[[hash_[A 0](0)]]-> hasher | hasher has Hasher + # hasher, [A] -[[hash_[A 0](0)]]-> hasher | hasher implements Hasher + # hasher, [A] -[[hash_[A 0](0)]]-> hasher | hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 0](0)]] #Derived.hash_[A 0] = \#Derived.hasher, A -> #Derived.hasher @@ -246,8 +246,8 @@ fn tag_one_label_newtype() { derive_test(Hash, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 2](0)]] #Derived.hash_[A 2] = @@ -263,8 +263,8 @@ fn tag_two_labels() { derive_test(Hash, v!([A v!(U8) v!(STR) v!(U16), B v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash, a3 has Hash - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash, a3 has Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash, a3 implements Hash # Specialization lambda sets: # @<1>: [[hash_[A 3,B 1](0)]] #Derived.hash_[A 3,B 1] = @@ -285,8 +285,8 @@ fn tag_two_labels_no_payloads() { derive_test(Hash, v!([A, B]), |golden| { assert_snapshot!(golden, @r###" # derived for [A, B] - # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a | a has Hasher - # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a | a has Hasher + # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a | a implements Hasher + # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a | a implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 0,B 0](0)]] #Derived.hash_[A 0,B 0] = @@ -304,8 +304,8 @@ fn recursive_tag_union() { derive_test(Hash, v!([Nil, Cons v!(U8) v!(^lst) ] as lst), |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a has Hasher, a1 has Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a has Hasher, a1 has Hash, a2 implements Hash # Specialization lambda sets: # @<1>: [[hash_[Cons 2,Nil 0](0)]] #Derived.hash_[Cons 2,Nil 0] = diff --git a/crates/compiler/test_gen/src/gen_abilities.rs b/crates/compiler/test_gen/src/gen_abilities.rs index 022765b7a05..99f706d4443 100644 --- a/crates/compiler/test_gen/src/gen_abilities.rs +++ b/crates/compiler/test_gen/src/gen_abilities.rs @@ -20,10 +20,10 @@ fn hash_specialization() { r#" app "test" provides [main] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash = \@Id n -> n @@ -43,14 +43,14 @@ fn hash_specialization_multiple_add() { r#" app "test" provides [main] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - Id := U64 has [ MHash {hash: hashId} ] + Id := U64 implements [ MHash {hash: hashId} ] hashId = \@Id n -> n - One := {} has [ MHash {hash: hashOne} ] + One := {} implements [ MHash {hash: hashOne} ] hashOne = \@One _ -> 1 @@ -70,10 +70,10 @@ fn alias_member_specialization() { r#" app "test" provides [main] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash = \@Id n -> n @@ -95,13 +95,13 @@ fn ability_constrained_in_non_member_usage() { r#" app "test" provides [result] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - mulMHashes : a, a -> U64 | a has MHash + mulMHashes : a, a -> U64 | a implements MHash mulMHashes = \x, y -> hash x * hash y - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash = \@Id n -> n result = mulMHashes (@Id 5) (@Id 7) @@ -120,12 +120,12 @@ fn ability_constrained_in_non_member_usage_inferred() { r#" app "test" provides [result] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash mulMHashes = \x, y -> hash x * hash y - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash = \@Id n -> n result = mulMHashes (@Id 5) (@Id 7) @@ -144,16 +144,16 @@ fn ability_constrained_in_non_member_multiple_specializations() { r#" app "test" provides [result] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - mulMHashes : a, b -> U64 | a has MHash, b has MHash + mulMHashes : a, b -> U64 | a implements MHash, b implements MHash mulMHashes = \x, y -> hash x * hash y - Id := U64 has [MHash { hash: hashId }] + Id := U64 implements [MHash { hash: hashId }] hashId = \@Id n -> n - Three := {} has [MHash { hash: hashThree }] + Three := {} implements [MHash { hash: hashThree }] hashThree = \@Three _ -> 3 result = mulMHashes (@Id 100) (@Three {}) @@ -172,15 +172,15 @@ fn ability_constrained_in_non_member_multiple_specializations_inferred() { r#" app "test" provides [result] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash mulMHashes = \x, y -> hash x * hash y - Id := U64 has [MHash { hash: hashId }] + Id := U64 implements [MHash { hash: hashId }] hashId = \@Id n -> n - Three := {} has [MHash { hash: hashThree }] + Three := {} implements [MHash { hash: hashThree }] hashThree = \@Three _ -> 3 result = mulMHashes (@Id 100) (@Three {}) @@ -199,16 +199,16 @@ fn ability_used_as_type_still_compiles() { r#" app "test" provides [result] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash mulMHashes : MHash, MHash -> U64 mulMHashes = \x, y -> hash x * hash y - Id := U64 has [MHash { hash: hashId }] + Id := U64 implements [MHash { hash: hashId }] hashId = \@Id n -> n - Three := {} has [MHash { hash: hashThree }] + Three := {} implements [MHash { hash: hashThree }] hashThree = \@Three _ -> 3 result = mulMHashes (@Id 100) (@Three {}) @@ -227,15 +227,15 @@ fn bounds_to_multiple_abilities() { r#" app "test" provides [main] to "./platform" - Idempot has idempot : a -> a | a has Idempot - Consume has consume : a -> Str | a has Consume + Idempot implements idempot : a -> a | a implements Idempot + Consume implements consume : a -> Str | a implements Consume - Hello := Str has [Idempot { idempot: idempotHello }, Consume { consume: consumeHello }] + Hello := Str implements [Idempot { idempot: idempotHello }, Consume { consume: consumeHello }] idempotHello = \@Hello msg -> @Hello msg consumeHello = \@Hello msg -> msg - lifecycle : a -> Str | a has Idempot & Consume + lifecycle : a -> Str | a implements Idempot & Consume lifecycle = \x -> idempot x |> consume main = lifecycle (@Hello "hello world") @@ -254,26 +254,26 @@ fn encode() { r#" app "test" provides [myU8Bytes] to "./platform" - MEncoder fmt := List U8, fmt -> List U8 | fmt has Format + MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format - MEncoding has - toEncoder : val -> MEncoder fmt | val has MEncoding, fmt has Format + MEncoding implements + toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format - Format has - u8 : U8 -> MEncoder fmt | fmt has Format + Format implements + u8 : U8 -> MEncoder fmt | fmt implements Format - appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt has Format + appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt implements Format appendWith = \lst, (@MEncoder doFormat), fmt -> doFormat lst fmt - toBytes : val, fmt -> List U8 | val has MEncoding, fmt has Format + toBytes : val, fmt -> List U8 | val implements MEncoding, fmt implements Format toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt - Linear := {} has [Format {u8}] + Linear := {} implements [Format {u8}] u8 = \n -> @MEncoder (\lst, @Linear {} -> List.append lst n) - Rgba := { r : U8, g : U8, b : U8, a : U8 } has [MEncoding {toEncoder}] + Rgba := { r : U8, g : U8, b : U8, a : U8 } implements [MEncoding {toEncoder}] toEncoder = \@Rgba {r, g, b, a} -> @MEncoder \lst, fmt -> lst @@ -301,19 +301,19 @@ fn decode() { MDecodeError : [TooShort, Leftover (List U8)] - MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt has MDecoderFormatting + MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting - MDecoding has - decoder : MDecoder val fmt | val has MDecoding, fmt has MDecoderFormatting + MDecoding implements + decoder : MDecoder val fmt | val implements MDecoding, fmt implements MDecoderFormatting - MDecoderFormatting has - u8 : MDecoder U8 fmt | fmt has MDecoderFormatting + MDecoderFormatting implements + u8 : MDecoder U8 fmt | fmt implements MDecoderFormatting - decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt has MDecoderFormatting + decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting decodeWith = \lst, (@MDecoder doDecode), fmt -> doDecode lst fmt fromBytes : List U8, fmt -> Result val MDecodeError - | fmt has MDecoderFormatting, val has MDecoding + | fmt implements MDecoderFormatting, val implements MDecoding fromBytes = \lst, fmt -> when decodeWith lst decoder fmt is { result, rest } -> @@ -323,14 +323,14 @@ fn decode() { else Err (Leftover rest) - Linear := {} has [MDecoderFormatting {u8}] + Linear := {} implements [MDecoderFormatting {u8}] u8 = @MDecoder \lst, @Linear {} -> when List.first lst is Ok n -> { result: Ok n, rest: List.dropFirst lst } Err _ -> { result: Err TooShort, rest: [] } - MyU8 := U8 has [MDecoding {decoder}] + MyU8 := U8 implements [MDecoding {decoder}] # impl MDecoding for MyU8 decoder = @MDecoder \lst, fmt -> @@ -358,7 +358,7 @@ fn encode_use_stdlib() { imports [Encode, Json] provides [main] to "./platform" - HelloWorld := {} has [Encoding {toEncoder}] + HelloWorld := {} implements [Encoding {toEncoder}] toEncoder = \@HelloWorld {} -> Encode.custom \bytes, fmt -> bytes @@ -386,7 +386,7 @@ fn encode_use_stdlib_without_wrapping_custom() { imports [Encode, Json] provides [main] to "./platform" - HelloWorld := {} has [Encoding {toEncoder}] + HelloWorld := {} implements [Encoding {toEncoder}] toEncoder = \@HelloWorld {} -> Encode.string "Hello, World!\n" main = @@ -411,7 +411,7 @@ fn encode_derive_to_encoder_for_opaque() { imports [Json] provides [main] to "./platform" - HelloWorld := { a: Str } has [Encoding] + HelloWorld := { a: Str } implements [Encoding] main = result = Str.fromUtf8 (Encode.toBytes (@HelloWorld { a: "Hello, World!" }) Json.json) @@ -435,7 +435,7 @@ fn to_encoder_encode_custom_has_capture() { imports [Encode, Json] provides [main] to "./platform" - HelloWorld := Str has [Encoding {toEncoder}] + HelloWorld := Str implements [Encoding {toEncoder}] toEncoder = \@HelloWorld s1 -> Encode.custom \bytes, fmt -> bytes @@ -881,7 +881,7 @@ fn encode_derived_generic_record_with_different_field_types() { imports [Encode, Json] provides [main] to "./platform" - Q a b := {a: a, b: b} has [Encoding] + Q a b := {a: a, b: b} implements [Encoding] q = @Q {a: 10u32, b: "fieldb"} @@ -907,7 +907,7 @@ fn encode_derived_generic_tag_with_different_field_types() { imports [Encode, Json] provides [main] to "./platform" - Q a b := [A a, B b] has [Encoding] + Q a b := [A a, B b] implements [Encoding] q : Q Str U32 q = @Q (B 67) @@ -934,7 +934,7 @@ fn decode_use_stdlib() { imports [Json] provides [main] to "./platform" - MyNum := U8 has [Decoding {decoder: myDecoder}] + MyNum := U8 implements [Decoding {decoder: myDecoder}] myDecoder = Decode.custom \bytes, fmt -> @@ -968,7 +968,7 @@ fn decode_derive_decoder_for_opaque() { imports [Json] provides [main] to "./platform" - HelloWorld := { a: Str } has [Decoding] + HelloWorld := { a: Str } implements [Decoding] main = when Str.toUtf8 """{"a":"Hello, World!"}""" |> Decode.fromBytes Json.json is @@ -991,7 +991,7 @@ fn decode_use_stdlib_json_list() { imports [Json] provides [main] to "./platform" - MyNumList := List U8 has [Decoding {decoder: myDecoder}] + MyNumList := List U8 implements [Decoding {decoder: myDecoder}] myDecoder = Decode.custom \bytes, fmt -> @@ -1414,7 +1414,7 @@ mod hash { const TEST_HASHER: &str = indoc!( r#" - THasher := List U8 has [Hasher { + THasher := List U8 implements [Hasher { addBytes: tAddBytes, addU8: tAddU8, addU16: tAddU16, @@ -1947,7 +1947,7 @@ mod hash { {} - Q := {{ a: U8, b: U8, c: U8 }} has [Hash] + Q := {{ a: U8, b: U8, c: U8 }} implements [Hash] q = @Q {{ a: 15, b: 27, c: 31 }} @@ -2000,7 +2000,7 @@ mod eq { r#" app "test" provides [main] to "./platform" - LyingEq := U8 has [Eq {isEq}] + LyingEq := U8 implements [Eq {isEq}] isEq = \@LyingEq m, @LyingEq n -> m != n @@ -2026,7 +2026,7 @@ mod eq { r#" app "test" provides [main] to "./platform" - Q := ({} -> Str) has [Eq {isEq: isEqQ}] + Q := ({} -> Str) implements [Eq {isEq: isEqQ}] isEqQ = \@Q _, @Q _ -> Bool.true @@ -2046,7 +2046,7 @@ mod eq { r#" app "test" provides [main] to "./platform" - Q := ({} -> Str) has [Eq {isEq: isEqQ}] + Q := ({} -> Str) implements [Eq {isEq: isEqQ}] isEqQ = \@Q f1, @Q f2 -> (f1 {} == f2 {}) @@ -2080,7 +2080,7 @@ mod eq { r#" app "test" provides [main] to "./platform" - Q := U8 has [Eq] + Q := U8 implements [Eq] main = (@Q 15) == (@Q 15) "# diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index c859ebf2f2f..f343ea78308 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -960,7 +960,7 @@ fn list_walk_implements_position() { r#" Option a : [Some a, None] - find : List a, a -> Option Nat | a has Eq + find : List a, a -> Option Nat | a implements Eq find = \list, needle -> findHelp list needle |> .v @@ -3693,7 +3693,7 @@ fn list_walk_backwards_implements_position() { r#" Option a : [Some a, None] - find : List a, a -> Option Nat | a has Eq + find : List a, a -> Option Nat | a implements Eq find = \list, needle -> findHelp list needle |> .v diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs index e29b62f71ed..95df22275da 100644 --- a/crates/compiler/test_gen/src/gen_num.rs +++ b/crates/compiler/test_gen/src/gen_num.rs @@ -891,7 +891,7 @@ fn gen_wrap_int_neq() { assert_evals_to!( indoc!( r#" - wrappedNotEq : a, a -> Bool | a has Eq + wrappedNotEq : a, a -> Bool | a implements Eq wrappedNotEq = \num1, num2 -> num1 != num2 diff --git a/crates/compiler/test_mono/src/tests.rs b/crates/compiler/test_mono/src/tests.rs index 11296395a98..703ea122e8c 100644 --- a/crates/compiler/test_mono/src/tests.rs +++ b/crates/compiler/test_mono/src/tests.rs @@ -1344,10 +1344,10 @@ fn specialize_ability_call() { r#" app "test" provides [main] to "./platform" - MHash has - hash : a -> U64 | a has MHash + MHash implements + hash : a -> U64 | a implements MHash - Id := U64 has [MHash {hash}] + Id := U64 implements [MHash {hash}] hash : Id -> U64 hash = \@Id n -> n @@ -1380,20 +1380,20 @@ fn encode() { r#" app "test" provides [myU8Bytes] to "./platform" - MEncoder fmt := List U8, fmt -> List U8 | fmt has Format + MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format - MEncoding has - toEncoder : val -> MEncoder fmt | val has MEncoding, fmt has Format + MEncoding implements + toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format - Format has - u8 : U8 -> MEncoder fmt | fmt has Format + Format implements + u8 : U8 -> MEncoder fmt | fmt implements Format - Linear := {} has [Format {u8}] + Linear := {} implements [Format {u8}] u8 = \n -> @MEncoder (\lst, @Linear {} -> List.append lst n) - MyU8 := U8 has [MEncoding {toEncoder}] + MyU8 := U8 implements [MEncoding {toEncoder}] toEncoder = \@MyU8 n -> u8 n @@ -2600,20 +2600,20 @@ fn unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unifica r#" app "test" provides [main] to "./platform" - MEncoder fmt := List U8, fmt -> List U8 | fmt has Format + MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format - MEncoding has - toEncoder : val -> MEncoder fmt | val has MEncoding, fmt has Format + MEncoding implements + toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format - Format has - u8 : {} -> MEncoder fmt | fmt has Format - str : {} -> MEncoder fmt | fmt has Format - tag : MEncoder fmt -> MEncoder fmt | fmt has Format + Format implements + u8 : {} -> MEncoder fmt | fmt implements Format + str : {} -> MEncoder fmt | fmt implements Format + tag : MEncoder fmt -> MEncoder fmt | fmt implements Format - Linear := {} has [Format {u8: lU8, str: lStr, tag: lTag}] + Linear := {} implements [Format {u8: lU8, str: lStr, tag: lTag}] - MU8 := U8 has [MEncoding {toEncoder: toEncoderU8}] - MStr := Str has [MEncoding {toEncoder: toEncoderStr}] + MU8 := U8 implements [MEncoding {toEncoder: toEncoderU8}] + MStr := Str implements [MEncoding {toEncoder: toEncoderStr}] Q a b := { a: a, b: b } @@ -2663,7 +2663,7 @@ fn unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unifica r#" app "test" imports [Json] provides [main] to "./platform" - Q a b := { a: a, b: b } has [Encoding {toEncoder: toEncoderQ}] + Q a b := { a: a, b: b } implements [Encoding {toEncoder: toEncoderQ}] toEncoderQ = \@Q t -> Encode.custom \bytes, fmt -> @@ -2701,7 +2701,7 @@ fn unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_ty r#" app "test" imports [Json] provides [main] to "./platform" - Q a b := { a: a, b: b } has [Encoding {toEncoder: toEncoderQ}] + Q a b := { a: a, b: b } implements [Encoding {toEncoder: toEncoderQ}] toEncoderQ = \@Q t -> Encode.custom \bytes, fmt -> diff --git a/crates/compiler/test_syntax/fuzz/dict.txt b/crates/compiler/test_syntax/fuzz/dict.txt index 805712e5ff2..6368aa3e2dc 100644 --- a/crates/compiler/test_syntax/fuzz/dict.txt +++ b/crates/compiler/test_syntax/fuzz/dict.txt @@ -6,7 +6,7 @@ "is" "expect" "dbg" -"has" +"implements" "app" "platform" diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc index d6df16d2872..3b411cb332c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc @@ -1,4 +1,4 @@ -MEq has - eq b c : a, a -> U64 | a has MEq +MEq implements + eq b c : a, a -> U64 | a implements MEq 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc index f07901e9cc6..8d0aa047c93 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc @@ -1,5 +1,5 @@ -MEq has - eq : a, a -> U64 | a has MEq - neq : a, a -> U64 | a has MEq +MEq implements + eq : a, a -> U64 | a implements MEq + neq : a, a -> U64 | a implements MEq 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc index 3b76e70bc26..92086a5f159 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc @@ -1,4 +1,4 @@ -MEq has -eq : a, a -> U64 | a has MEq +MEq implements +eq : a, a -> U64 | a implements MEq 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.roc index 0651010e941..02772c6ee72 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.roc @@ -1,4 +1,4 @@ -MEq has +MEq implements 123 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.formatted.roc index 9f2662a2479..4056155950d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.formatted.roc @@ -1,4 +1,4 @@ -Hash has +Hash implements hash : a -> U64 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.roc index 5e218feb6e0..02de08c9ec3 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.roc @@ -1,4 +1,4 @@ -Hash has +Hash implements hash : a -> U64 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.formatted.roc index 56efcb2abc8..740886df35c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.formatted.roc @@ -1,4 +1,4 @@ -Hash has +Hash implements hash : a -> U64 hash2 : a -> U64 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.roc index 795c19bad66..43b178a6bd9 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.roc @@ -1,4 +1,4 @@ -Hash has +Hash implements hash : a -> U64 hash2 : a -> U64 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc index c3d8e53fab0..798560ef410 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc @@ -1,3 +1,3 @@ -Hash has hash : a -> U64 | a has Hash +Hash implements hash : a -> U64 | a implements Hash 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc index f747842c70c..1c5fad72e51 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc @@ -1,5 +1,5 @@ -Ab1 has ab1 : a -> {} | a has Ab1 +Ab1 implements ab1 : a -> {} | a implements Ab1 -Ab2 has ab2 : a -> {} | a has Ab2 +Ab2 implements ab2 : a -> {} | a implements Ab2 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc index 783b9d8c175..32173c522a0 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc @@ -1,24 +1,24 @@ -A := U8 has [Eq, Hash] +A := U8 implements [Eq, Hash] -A := a | a has Other - has [Eq, Hash] +A := a | a implements Other + implements [Eq, Hash] -A := a | a has Other - has [Eq, Hash] +A := a | a implements Other + implements [Eq, Hash] -A := U8 has [Eq { eq }, Hash { hash }] +A := U8 implements [Eq { eq }, Hash { hash }] -A := U8 has [Eq { eq, eq1 }] +A := U8 implements [Eq { eq, eq1 }] -A := U8 has [Eq { eq, eq1 }, Hash] +A := U8 implements [Eq { eq, eq1 }, Hash] -A := U8 has [Hash, Eq { eq, eq1 }] +A := U8 implements [Hash, Eq { eq, eq1 }] -A := U8 has [] +A := U8 implements [] -A := a | a has Other - has [Eq { eq }, Hash { hash }] +A := a | a implements Other + implements [Eq { eq }, Hash { hash }] -A := U8 has [Eq {}] +A := U8 implements [Eq {}] 0 \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc index f8f0fe9e294..3228574abca 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc @@ -1,23 +1,23 @@ -A := U8 has [Eq, Hash] +A := U8 implements [Eq, Hash] -A := a | a has Other has [Eq, Hash] +A := a | a implements Other implements [Eq, Hash] -A := a | a has Other - has [Eq, Hash] +A := a | a implements Other + implements [Eq, Hash] -A := U8 has [Eq {eq}, Hash {hash}] +A := U8 implements [Eq {eq}, Hash {hash}] -A := U8 has [Eq {eq, eq1}] +A := U8 implements [Eq {eq, eq1}] -A := U8 has [Eq {eq, eq1}, Hash] +A := U8 implements [Eq {eq, eq1}, Hash] -A := U8 has [Hash, Eq {eq, eq1}] +A := U8 implements [Hash, Eq {eq, eq1}] -A := U8 has [] +A := U8 implements [] -A := a | a has Other - has [Eq {eq}, Hash {hash}] +A := a | a implements Other + implements [Eq {eq}, Hash {hash}] -A := U8 has [Eq {}] +A := U8 implements [Eq {}] 0 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc index ede845156aa..6b11f13621c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a has A +f : a -> (b -> c) | a implements A f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc index 333e60e19ba..70a5869e419 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc @@ -1,5 +1,5 @@ -f : a -> b | a has Hash & Eq, b has Eq & Hash & Display +f : a -> b | a implements Hash & Eq, b implements Eq & Hash & Display -f : a -> b | a has Hash & Eq, b has Hash & Display & Eq +f : a -> b | a implements Hash & Eq, b implements Hash & Display & Eq f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc index 29f4f890261..2a151bfd52b 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc @@ -1,7 +1,7 @@ -f : a -> b | a has Hash & Eq, b has Eq & Hash & Display +f : a -> b | a implements Hash & Eq, b implements Eq & Hash & Display f : a -> b - | a has Hash & Eq, - b has Hash & Display & Eq + | a implements Hash & Eq, + b implements Hash & Display & Eq f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc index a56e9fb1849..4de00586ac5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a has A, b has Eq, c has Ord +f : a -> (b -> c) | a implements A, b implements Eq, c implements Ord f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc index 8ca6701ffce..1e2868883eb 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a has Hash, b has Eq, c has Ord +f : a -> (b -> c) | a has Hash, b has Eq, c implements Ord f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc index a5e89f075f4..98fd1445413 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc @@ -1,6 +1,6 @@ f : a -> (b -> c) - | a has Hash, - b has Eq, - c has Ord + | a implements Hash, + b implements Eq, + c implements Ord f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc index eb3374f9920..d60270f465b 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc @@ -1,3 +1,3 @@ -f : a | a has A +f : a | a implements A f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc index fb742eac391..bdef6cc7def 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc @@ -1,3 +1,3 @@ -f : a -> U64 | a has Hash +f : a -> U64 | a implements Hash f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc index 7f29c770d39..050ad469105 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc @@ -1,4 +1,4 @@ f : a -> U64 - | a has Hash + | a implements Hash f diff --git a/crates/compiler/test_syntax/tests/test_fmt.rs b/crates/compiler/test_syntax/tests/test_fmt.rs index 751b3f080b4..8d092432bf5 100644 --- a/crates/compiler/test_syntax/tests/test_fmt.rs +++ b/crates/compiler/test_syntax/tests/test_fmt.rs @@ -5428,7 +5428,7 @@ mod test_fmt { fn opaque_has_clause() { expr_formats_same(indoc!( r#" - A := U8 has [Eq, Hash] + A := U8 implements [Eq, Hash] 0 "# @@ -5439,7 +5439,7 @@ mod test_fmt { r#" A := U8 - has [Eq, Hash] + implements [Eq, Hash] 0 "# @@ -5447,7 +5447,7 @@ mod test_fmt { indoc!( r#" A := U8 - has [Eq, Hash] + implements [Eq, Hash] 0 "# @@ -5457,15 +5457,15 @@ mod test_fmt { expr_formats_to( indoc!( r#" - A := a | a has Hash has [ Eq, Hash ] + A := a | a implements Hash implements [ Eq, Hash ] 0 "# ), indoc!( r#" - A := a | a has Hash - has [Eq, Hash] + A := a | a implements Hash + implements [Eq, Hash] 0 "# @@ -5475,14 +5475,14 @@ mod test_fmt { expr_formats_to( indoc!( r#" - A := U8 has [] + A := U8 implements [] 0 "# ), indoc!( r#" - A := U8 has [] + A := U8 implements [] 0 "# @@ -5525,7 +5525,7 @@ mod test_fmt { fn opaque_has_with_impls() { expr_formats_same(indoc!( r#" - A := U8 has [Eq { eq }, Hash { hash }] + A := U8 implements [Eq { eq }, Hash { hash }] 0 "# @@ -5533,7 +5533,7 @@ mod test_fmt { expr_formats_same(indoc!( r#" - A := U8 has [Eq { eq, eq1 }] + A := U8 implements [Eq { eq, eq1 }] 0 "# @@ -5542,8 +5542,8 @@ mod test_fmt { expr_formats_to( indoc!( r#" - A := U8 has [Eq { eq, eq1 }] - A := U8 has [Eq { + A := U8 implements [Eq { eq, eq1 }] + A := U8 implements [Eq { eq, eq1 }] @@ -5553,8 +5553,8 @@ mod test_fmt { ), indoc!( r#" - A := U8 has [Eq { eq, eq1 }] - A := U8 has [ + A := U8 implements [Eq { eq, eq1 }] + A := U8 implements [ Eq { eq, eq1, @@ -5568,8 +5568,8 @@ mod test_fmt { expr_formats_same(indoc!( r#" - A := a | a has Other - has [Eq { eq }, Hash { hash }] + A := a | a implements Other + implements [Eq { eq }, Hash { hash }] 0 "# @@ -5577,7 +5577,7 @@ mod test_fmt { expr_formats_same(indoc!( r#" - A := U8 has [Eq {}] + A := U8 implements [Eq {}] 0 "# @@ -5625,7 +5625,7 @@ mod test_fmt { dataIndices : List Nat, data : List (T k v), size : Nat, - } | k has Hash & Eq + } | k implements Hash & Eq a "# @@ -5837,12 +5837,12 @@ mod test_fmt { r#" interface Foo exposes [] imports [] - A has + A implements ## This is member ab - ab : a -> a | a has A + ab : a -> a | a implements A ## This is member de - de : a -> a | a has A + de : a -> a | a implements A f = g "# @@ -5884,7 +5884,7 @@ mod test_fmt { fn clauses_with_multiple_abilities() { expr_formats_same(indoc!( r#" - f : {} -> a | a has Eq & Hash & Decode + f : {} -> a | a implements Eq & Hash & Decode f "# @@ -5893,8 +5893,8 @@ mod test_fmt { expr_formats_to( indoc!( r#" - f : {} -> a | a has Eq & Hash & Decode, - b has Eq & Hash + f : {} -> a | a implements Eq & Hash & Decode, + b implements Eq & Hash f "# @@ -5902,10 +5902,10 @@ mod test_fmt { indoc!( // TODO: ideally, this would look a bit nicer - consider // f : {} -> a - // | a has Eq & Hash & Decode, - // b has Eq & Hash + // | a implements Eq & Hash & Decode, + // b implements Eq & Hash r#" - f : {} -> a | a has Eq & Hash & Decode, b has Eq & Hash + f : {} -> a | a implements Eq & Hash & Decode, b implements Eq & Hash f "# diff --git a/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt b/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt index 8efd15d88d0..6cc44c9d8b9 100644 --- a/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt +++ b/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt @@ -1,7 +1,7 @@ # +opt infer:print_only_under_alias app "test" provides [main] to "./platform" -F a : a | a has Hash +F a : a | a implements Hash main : F a -> F a -#^^^^{-1} a -[[main(0)]]-> a | a has Hash +#^^^^{-1} a -[[main(0)]]-> a | a implements Hash diff --git a/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt b/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt index 5379b86d509..4d18952a60e 100644 --- a/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt +++ b/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt @@ -1,7 +1,7 @@ # +opt infer:print_only_under_alias app "test" provides [main] to "./platform" -F a : a | a has Hash & Eq & Decoding +F a : a | a implements Hash & Eq & Decoding main : F a -> F a -#^^^^{-1} a -[[main(0)]]-> a | a has Hash & Decoding & Eq +#^^^^{-1} a -[[main(0)]]-> a | a implements Hash & Decoding & Eq diff --git a/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt b/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt index f262ca22658..a06679108d5 100644 --- a/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt +++ b/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -f : x -> x | x has Hash -g : x -> x | x has Decoding & Encoding +f : x -> x | x implements Hash +g : x -> x | x implements Decoding & Encoding -main : x -> x | x has Hash & Decoding & Encoding +main : x -> x | x implements Hash & Decoding & Encoding main = \x -> x |> f |> g -#^^^^{-1} x -[[main(0)]]-> x | x has Hash & Encoding & Decoding +#^^^^{-1} x -[[main(0)]]-> x | x implements Hash & Encoding & Decoding diff --git a/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt b/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt index da1662ffa2a..3868cf4d177 100644 --- a/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt +++ b/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt @@ -1,6 +1,6 @@ app "test" provides [top] to "./platform" -MDict u := (List u) | u has Hash & Eq +MDict u := (List u) | u implements Hash & Eq bot : MDict k -> MDict k bot = \@MDict data -> @@ -9,4 +9,4 @@ bot = \@MDict data -> top : MDict v -> MDict v top = \x -> bot x -#^^^{-1} MDict v -[[top(0)]]-> MDict v | v has Hash & Eq +#^^^{-1} MDict v -[[top(0)]]-> MDict v | v implements Hash & Eq diff --git a/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets.txt b/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets.txt index 57d44ca2891..3198cd1bf3a 100644 --- a/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets.txt +++ b/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets.txt @@ -1,6 +1,6 @@ app "test" provides [isEqQ] to "./platform" -Q := [ F (Str -> Str), G ] has [Eq { isEq: isEqQ }] +Q := [ F (Str -> Str), G ] implements [Eq { isEq: isEqQ }] isEqQ = \@Q q1, @Q q2 -> when T q1 q2 is #^^^^^{-1} Q, Q -[[isEqQ(0)]]-> Bool diff --git a/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets_material.txt b/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets_material.txt index a0a9335f0ba..b47c5af1549 100644 --- a/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets_material.txt +++ b/crates/compiler/uitest/tests/ability/impl_ability_for_opaque_with_lambda_sets_material.txt @@ -1,7 +1,7 @@ # +opt infer:print_only_under_alias app "test" provides [main] to "./platform" -Q := ({} -> Str) has [Eq {isEq: isEqQ}] +Q := ({} -> Str) implements [Eq {isEq: isEqQ}] isEqQ = \@Q f1, @Q f2 -> (f1 {} == f2 {}) #^^^^^{-1} ({} -[[]]-> Str), ({} -[[]]-> Str) -[[isEqQ(2)]]-> [False, True] diff --git a/crates/compiler/uitest/tests/ability/smoke/decoder.txt b/crates/compiler/uitest/tests/ability/smoke/decoder.txt index de7b54136f8..987ba167340 100644 --- a/crates/compiler/uitest/tests/ability/smoke/decoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/decoder.txt @@ -2,19 +2,19 @@ app "test" provides [myU8] to "./platform" MDecodeError : [TooShort, Leftover (List U8)] -MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt has MDecoderFormatting +MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting MDecoding has - decoder : MDecoder val fmt | val has MDecoding, fmt has MDecoderFormatting + decoder : MDecoder val fmt | val has MDecoding, fmt implements MDecoderFormatting MDecoderFormatting has - u8 : MDecoder U8 fmt | fmt has MDecoderFormatting + u8 : MDecoder U8 fmt | fmt implements MDecoderFormatting -decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt has MDecoderFormatting +decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting decodeWith = \lst, (@MDecoder doDecode), fmt -> doDecode lst fmt fromBytes : List U8, fmt -> Result val MDecodeError - | fmt has MDecoderFormatting, val has MDecoding + | fmt has MDecoderFormatting, val implements MDecoding fromBytes = \lst, fmt -> when decodeWith lst decoder fmt is { result, rest } -> @@ -23,7 +23,7 @@ fromBytes = \lst, fmt -> Err e -> Err e -Linear := {} has [MDecoderFormatting {u8}] +Linear := {} implements [MDecoderFormatting {u8}] u8 = @MDecoder \lst, @Linear {} -> #^^{-1} Linear#u8(11): MDecoder U8 Linear @@ -31,10 +31,10 @@ u8 = @MDecoder \lst, @Linear {} -> Ok n -> { result: Ok n, rest: List.dropFirst lst } Err _ -> { result: Err TooShort, rest: [] } -MyU8 := U8 has [MDecoding {decoder}] +MyU8 := U8 implements [MDecoding {decoder}] decoder = @MDecoder \lst, fmt -> -#^^^^^^^{-1} MyU8#decoder(12): MDecoder MyU8 fmt | fmt has MDecoderFormatting +#^^^^^^^{-1} MyU8#decoder(12): MDecoder MyU8 fmt | fmt implements MDecoderFormatting when decodeWith lst u8 fmt is { result, rest } -> { result: Result.map result (\n -> @MyU8 n), rest } diff --git a/crates/compiler/uitest/tests/ability/smoke/encoder.txt b/crates/compiler/uitest/tests/ability/smoke/encoder.txt index 57c37aef4c3..a4a74c6822d 100644 --- a/crates/compiler/uitest/tests/ability/smoke/encoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/encoder.txt @@ -1,29 +1,29 @@ app "test" provides [myU8Bytes] to "./platform" -MEncoder fmt := List U8, fmt -> List U8 | fmt has Format +MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format MEncoding has - toEncoder : val -> MEncoder fmt | val has MEncoding, fmt has Format + toEncoder : val -> MEncoder fmt | val has MEncoding, fmt implements Format Format has - u8 : U8 -> MEncoder fmt | fmt has Format + u8 : U8 -> MEncoder fmt | fmt implements Format -appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt has Format +appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt implements Format appendWith = \lst, (@MEncoder doFormat), fmt -> doFormat lst fmt -toBytes : val, fmt -> List U8 | val has MEncoding, fmt has Format +toBytes : val, fmt -> List U8 | val has MEncoding, fmt implements Format toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt -Linear := {} has [Format {u8}] +Linear := {} implements [Format {u8}] u8 = \n -> @MEncoder (\lst, @Linear {} -> List.append lst n) #^^{-1} Linear#u8(10): U8 -[[u8(10)]]-> MEncoder Linear -MyU8 := U8 has [MEncoding {toEncoder}] +MyU8 := U8 implements [MEncoding {toEncoder}] toEncoder = \@MyU8 n -> u8 n -#^^^^^^^^^{-1} MyU8#toEncoder(11): MyU8 -[[toEncoder(11)]]-> MEncoder fmt | fmt has Format +#^^^^^^^^^{-1} MyU8#toEncoder(11): MyU8 -[[toEncoder(11)]]-> MEncoder fmt | fmt implements Format myU8Bytes = toBytes (@MyU8 15) (@Linear {}) #^^^^^^^^^{-1} List U8 diff --git a/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt b/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt index ac21c79e7a2..020da7aefc8 100644 --- a/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt +++ b/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt @@ -3,4 +3,4 @@ app "test" provides [main] to "./platform" main : Decoder Bool _ main = Decode.custom \bytes, fmt -> Decode.decodeWith bytes Decode.decoder fmt - # ^^^^^^^^^^^^^^ Decoding#Decode.decoder(4): Decoder Bool fmt | fmt has DecoderFormatting + # ^^^^^^^^^^^^^^ Decoding#Decode.decoder(4): Decoder Bool fmt | fmt implements DecoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt b/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt index 2c03583a117..fa6c3cccc02 100644 --- a/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt +++ b/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt @@ -2,4 +2,4 @@ app "test" provides [main] to "./platform" main = \h -> Hash.hash h Bool.true - # ^^^^^^^^^ Hash#Hash.hash(1): a, Bool -[[Hash.hashBool(9)]]-> a | a has Hasher + # ^^^^^^^^^ Hash#Hash.hash(1): a, Bool -[[Hash.hashBool(9)]]-> a | a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt b/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt index b08a6a8325e..e2c68883730 100644 --- a/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt +++ b/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt @@ -1,4 +1,4 @@ app "test" provides [main] to "./platform" main = Encode.toEncoder Bool.true -# ^^^^^^^^^^^^^^^^ Encoding#Encode.toEncoder(2): Bool -[[] + fmt:Encode.bool(17):1]-> Encoder fmt | fmt has EncoderFormatting +# ^^^^^^^^^^^^^^^^ Encoding#Encode.toEncoder(2): Bool -[[] + fmt:Encode.bool(17):1]-> Encoder fmt | fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt index 65a68da3a48..13105803adb 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt @@ -1,9 +1,9 @@ # +opt infer:print_only_under_alias app "test" provides [main] to "./platform" -N := U8 has [Decoding] +N := U8 implements [Decoding] main : Decoder N _ main = Decode.custom \bytes, fmt -> Decode.decodeWith bytes Decode.decoder fmt -# ^^^^^^^^^^^^^^ N#Decode.decoder(3): List U8, fmt -[[7]]-> { rest : List U8, result : [Err [TooShort], Ok U8] } | fmt has DecoderFormatting +# ^^^^^^^^^^^^^^ N#Decode.decoder(3): List U8, fmt -[[7]]-> { rest : List U8, result : [Err [TooShort], Ok U8] } | fmt implements DecoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt index 0deb0fef599..71decfe1295 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -N := U8 has [Encoding] +N := U8 implements [Encoding] main = Encode.toEncoder (@N 15) -# ^^^^^^^^^^^^^^^^ N#Encode.toEncoder(3): N -[[#N_toEncoder(3)]]-> Encoder fmt | fmt has EncoderFormatting +# ^^^^^^^^^^^^^^^^ N#Encode.toEncoder(3): N -[[#N_toEncoder(3)]]-> Encoder fmt | fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_eq_custom.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_eq_custom.txt index 9d83310b13c..8cb1c64cc78 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_eq_custom.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_eq_custom.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Trivial := {} has [Eq {isEq}] +Trivial := {} implements [Eq {isEq}] isEq = \@Trivial {}, @Trivial {} -> Bool.true diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_eq_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_eq_derive.txt index cb840d7d282..173fd0674d4 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_eq_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_eq_derive.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -N := U8 has [Eq] +N := U8 implements [Eq] main = Bool.isEq (@N 15) (@N 23) # ^^^^^^^^^ N#Bool.isEq(3): N, N -[[#N_isEq(3)]]-> Bool diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt index 4fb63b7df7a..957352040cc 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -Noop := {} has [Hash {hash}] +Noop := {} implements [Hash {hash}] hash = \hasher, @Noop {} -> hasher main = \hasher -> hash hasher (@Noop {}) -#^^^^{-1} hasher -[[main(0)]]-> hasher | hasher has Hasher +#^^^^{-1} hasher -[[main(0)]]-> hasher | hasher implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt index 250e788a1cf..b9aabd1cc55 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -N := U8 has [Hash] +N := U8 implements [Hash] main = \hasher, @N n -> Hash.hash hasher (@N n) -# ^^^^^^^^^ N#Hash.hash(3): a, N -[[#N_hash(3)]]-> a | a has Hasher +# ^^^^^^^^^ N#Hash.hash(3): a, N -[[#N_hash(3)]]-> a | a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt index 010746a21b3..dfe79b44ae1 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt @@ -1,13 +1,13 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a has F, b has G -G has g : b -> {} | b has G +F has f : a -> (b -> {}) | a has F, b implements G +G has g : b -> {} | b implements G -Fo := {} has [F {f}] +Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b has G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G -Go := {} has [G {g}] +Go := {} implements [G {g}] g = \@Go {} -> {} #^{-1} Go#g(8): Go -[[g(8)]]-> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt index ab0dac137f8..45a01d058d8 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt @@ -1,13 +1,13 @@ app "test" provides [main] to "./platform" -F has f : a -> ({} -> b) | a has F, b has G -G has g : {} -> b | b has G +F has f : a -> ({} -> b) | a has F, b implements G +G has g : {} -> b | b implements G -Fo := {} has [F {f}] +Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> ({} -[[] + b:g(4):1]-> b) | b has G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> ({} -[[] + b:g(4):1]-> b) | b implements G -Go := {} has [G {g}] +Go := {} implements [G {g}] g = \{} -> @Go {} #^{-1} Go#g(8): {} -[[g(8)]]-> Go diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt index 242be084996..8b7e092a806 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt @@ -1,15 +1,15 @@ app "test" provides [f] to "./platform" -J has j : j -> (k -> {}) | j has J, k has K -K has k : k -> {} | k has K +J has j : j -> (k -> {}) | j has J, k implements K +K has k : k -> {} | k implements K -C := {} has [J {j: jC}] +C := {} implements [J {j: jC}] jC = \@C _ -> k -D := {} has [J {j: jD}] +D := {} implements [J {j: jD}] jD = \@D _ -> k -E := {} has [K {k}] +E := {} implements [K {k}] k = \@E _ -> {} f = \flag, a, c -> @@ -18,5 +18,5 @@ f = \flag, a, c -> A -> j a B -> j a it c -# ^ k | k has K -# ^^ k -[[] + j:j(2):2]-> {} | j has J, k has K +# ^ k | k implements K +# ^^ k -[[] + j:j(2):2]-> {} | j has J, k implements K diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt index a71e0898aae..0209cfbdb01 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt @@ -1,32 +1,32 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) | j has J, k has K -K has k : k -> {} | k has K +J has j : j -> (k -> {}) | j has J, k implements K +K has k : k -> {} | k implements K -C := {} has [J {j: jC}] +C := {} implements [J {j: jC}] jC = \@C _ -> k -#^^{-1} C -[[jC(8)]]-> (k -[[] + k:k(4):1]-> {}) | k has K +#^^{-1} C -[[jC(8)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K -D := {} has [J {j: jD}] +D := {} implements [J {j: jD}] jD = \@D _ -> k -#^^{-1} D -[[jD(9)]]-> (k -[[] + k:k(4):1]-> {}) | k has K +#^^{-1} D -[[jD(9)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K -E := {} has [K {k}] +E := {} implements [K {k}] k = \@E _ -> {} #^{-1} E#k(10): E -[[k(10)]]-> {} f = \flag, a, b -> -# ^ j | j has J -# ^ j | j has J +# ^ j | j implements J +# ^ j | j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k has K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j has J, j1 has J, k has K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j has J, j1 has J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k has K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k has K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K main = (f A (@C {}) (@D {})) (@E {}) # ^ [A, B], C, D -[[f(11)]]-> (E -[[k(10)]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt index 34a84a5d114..4a1dd5f38af 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt @@ -1,43 +1,43 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) | j has J, k has K -K has k : k -> {} | k has K +J has j : j -> (k -> {}) | j has J, k implements K +K has k : k -> {} | k implements K -C := {} has [J {j: jC}] +C := {} implements [J {j: jC}] jC = \@C _ -> k -#^^{-1} C -[[jC(9)]]-> (k -[[] + k:k(4):1]-> {}) | k has K +#^^{-1} C -[[jC(9)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K -D := {} has [J {j: jD}] +D := {} implements [J {j: jD}] jD = \@D _ -> k -#^^{-1} D -[[jD(10)]]-> (k -[[] + k:k(4):1]-> {}) | k has K +#^^{-1} D -[[jD(10)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K -E := {} has [K {k: kE}] +E := {} implements [K {k: kE}] kE = \@E _ -> {} #^^{-1} E -[[kE(11)]]-> {} -F := {} has [K {k: kF}] +F := {} implements [K {k: kF}] kF = \@F _ -> {} #^^{-1} F -[[kF(12)]]-> {} f = \flag, a, b -> -# ^ j | j has J -# ^ j | j has J +# ^ j | j implements J +# ^ j | j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k has K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j has J, j1 has J, k has K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j has J, j1 has J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k has K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k has K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K main = #^^^^{-1} {} it = \x -> -# ^^ k -[[it(21)]]-> {} | k has K +# ^^ k -[[it(21)]]-> {} | k implements K (f A (@C {}) (@D {})) x -# ^ [A, B], C, D -[[f(13)]]-> (k -[[] + k:k(4):1]-> {}) | k has K +# ^ [A, B], C, D -[[f(13)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K if Bool.true then it (@E {}) # ^^ E -[[it(21)]]-> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt index 1d1ab51d65f..3c155d1173e 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt @@ -1,13 +1,13 @@ app "test" provides [main] to "./platform" -F has f : a, b -> ({} -> ({} -> {})) | a has F, b has G -G has g : b -> ({} -> {}) | b has G +F has f : a, b -> ({} -> ({} -> {})) | a has F, b implements G +G has g : b -> ({} -> {}) | b implements G -Fo := {} has [F {f}] +Fo := {} implements [F {f}] f = \@Fo {}, b -> \{} -> g b -#^{-1} Fo#f(7): Fo, b -[[f(7)]]-> ({} -[[13 b]]-> ({} -[[] + b:g(4):2]-> {})) | b has G +#^{-1} Fo#f(7): Fo, b -[[f(7)]]-> ({} -[[13 b]]-> ({} -[[] + b:g(4):2]-> {})) | b implements G -Go := {} has [G {g}] +Go := {} implements [G {g}] g = \@Go {} -> \{} -> {} #^{-1} Go#g(8): Go -[[g(8)]]-> ({} -[[14]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt index fb24dd6496b..8f3d9427b97 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt @@ -1,13 +1,13 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a has F, b has G -G has g : b -> {} | b has G +F has f : a -> (b -> {}) | a has F, b implements G +G has g : b -> {} | b implements G -Fo := {} has [F {f}] +Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b has G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G -Go := {} has [G {g}] +Go := {} implements [G {g}] g = \@Go {} -> {} #^{-1} Go#g(8): Go -[[g(8)]]-> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt index 31cb72dd0f4..6a159a5e62d 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt @@ -1,19 +1,19 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a has F, b has G -G has g : b -> {} | b has G +F has f : a -> (b -> {}) | a has F, b implements G +G has g : b -> {} | b implements G -Fo := {} has [F {f}] +Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b has G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G -Go := {} has [G {g}] +Go := {} implements [G {g}] g = \@Go {} -> {} #^{-1} Go#g(8): Go -[[g(8)]]-> {} main = -#^^^^{-1} b -[[] + b:g(4):1]-> {} | b has G +#^^^^{-1} b -[[] + b:g(4):1]-> {} | b implements G h = f (@Fo {}) -# ^ Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b has G -# ^ b -[[] + b:g(4):1]-> {} | b has G +# ^ Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G +# ^ b -[[] + b:g(4):1]-> {} | b implements G h diff --git a/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt b/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt index fa65790b1fb..8653bb77c7c 100644 --- a/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt +++ b/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt @@ -2,4 +2,4 @@ app "test" provides [main] to "./platform" main = \h -> Hash.hash h 7 - # ^^^^^^^^^ Hash#Hash.hash(1): a, I64 -[[Hash.hashI64(13)]]-> a | a has Hasher + # ^^^^^^^^^ Hash#Hash.hash(1): a, I64 -[[Hash.hashI64(13)]]-> a | a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt index ac6dc4d2651..390df75dfbb 100644 --- a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt +++ b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt @@ -3,4 +3,4 @@ app "test" provides [main] to "./platform" main = toEncoder { a: "" } - # ^^^^^^^^^ Encoding#toEncoder(2): { a : Str } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt | fmt has EncoderFormatting + # ^^^^^^^^^ Encoding#toEncoder(2): { a : Str } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt | fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt index df9d14d788f..ba43f3905f5 100644 --- a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt +++ b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt @@ -2,8 +2,8 @@ app "test" imports [Encode.{ toEncoder, custom }] provides [main] to "./platform" -A := {} has [Encoding {toEncoder}] +A := {} implements [Encoding {toEncoder}] toEncoder = \@A _ -> custom \b, _ -> b main = toEncoder { a: @A {} } - # ^^^^^^^^^ Encoding#toEncoder(2): { a : A } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt | fmt has EncoderFormatting + # ^^^^^^^^^ Encoding#toEncoder(2): { a : A } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt | fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt index 68dfcf4582a..00439c028a2 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt @@ -1,9 +1,9 @@ app "test" provides [main] to "./platform" -Id1 has id1 : a -> a | a has Id1 -Id2 has id2 : a -> a | a has Id2 +Id1 has id1 : a -> a | a implements Id1 +Id2 has id2 : a -> a | a implements Id2 -A := {} has [Id1 {id1}, Id2 {id2}] +A := {} implements [Id1 {id1}, Id2 {id2}] id1 = \@A {} -> @A {} #^^^{-1} A#id1(6): A -[[id1(6)]]-> A diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt index 358f3fa0219..7fec6cf4b50 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a has Id +Id has id : a -> a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> @A {} #^^{-1} A#id(4): A -[[id(4)]]-> A diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt index 497b4a981c8..7fd08456e29 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a has Id +Id has id : a -> a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> @A {} #^^{-1} A#id(4): A -[[id(4)]]-> A diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt index 541a32b3cad..172090ca5b9 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt @@ -1,16 +1,16 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a has Id +Id has id : a -> a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> @A {} #^^{-1} A#id(4): A -[[id(4)]]-> A main = alias1 = \x -> id x - # ^^ Id#id(2): a -[[] + a:id(2):1]-> a | a has Id + # ^^ Id#id(2): a -[[] + a:id(2):1]-> a | a implements Id alias2 = \x -> alias1 x - # ^^^^^^ a -[[alias1(6)]]-> a | a has Id + # ^^^^^^ a -[[alias1(6)]]-> a | a implements Id a : A a = alias2 (@A {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt index af8b3f017a7..004c1d70cb9 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a has Id +Id has id : a -> a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> @A {} #^^{-1} A#id(4): A -[[id(4)]]-> A diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt index 91f70d7f7c0..91e20eb8f94 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt @@ -1,10 +1,10 @@ app "test" provides [main] to "./platform" Bounce has - ping : a -> a | a has Bounce - pong : a -> a | a has Bounce + ping : a -> a | a implements Bounce + pong : a -> a | a implements Bounce -A := {} has [Bounce {ping: pingA, pong: pongA}] +A := {} implements [Bounce {ping: pingA, pong: pongA}] pingA = \@A {} -> pong (@A {}) # ^^^^ A#pong(6): A -[[pongA(6)]]-> A diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt index 22b25a9adb0..a6af367fe12 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt @@ -1,10 +1,10 @@ app "test" provides [main] to "./platform" Bounce has - ping : a -> a | a has Bounce - pong : a -> a | a has Bounce + ping : a -> a | a implements Bounce + pong : a -> a | a implements Bounce -A := {} has [Bounce {ping, pong}] +A := {} implements [Bounce {ping, pong}] ping = \@A {} -> pong (@A {}) # ^^^^ A#pong(6): A -[[pong(6)]]-> A diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt index 6060616d708..db9090568e0 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -Diverge has diverge : a -> a | a has Diverge +Diverge has diverge : a -> a | a implements Diverge -A := {} has [Diverge {diverge}] +A := {} implements [Diverge {diverge}] diverge : A -> A diverge = \@A {} -> diverge (@A {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt index 4e85e6905c2..1b7828e9fe0 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt @@ -3,9 +3,9 @@ app "test" provides [main] to "./platform" Thunk a : {} -> a -Id has id : a -> Thunk a | a has Id +Id has id : a -> Thunk a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> \{} -> @A {} #^^{-1} A#id(5): {} -[[id(5)]]-> ({} -[[8]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt index b08f4795a25..2965caa4ad0 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt @@ -3,15 +3,15 @@ app "test" provides [main] to "./platform" Thunk a : {} -> a -Id has id : a -> Thunk a | a has Id +Id has id : a -> Thunk a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> \{} -> @A {} #^^{-1} A#id(5): {} -[[id(5)]]-> ({} -[[8]]-> {}) main = alias = \x -> id x - # ^^ Id#id(3): a -[[] + a:id(3):1]-> ({} -[[] + a:id(3):2]-> a) | a has Id + # ^^ Id#id(3): a -[[] + a:id(3):1]-> ({} -[[] + a:id(3):2]-> a) | a implements Id a : A a = (alias (@A {})) {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt index ab960558bc7..eec59f31094 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt @@ -3,9 +3,9 @@ app "test" provides [main] to "./platform" Thunk a := {} -> a -Id has id : a -> Thunk a | a has Id +Id has id : a -> Thunk a | a implements Id -A := {} has [Id {id}] +A := {} implements [Id {id}] id = \@A {} -> @Thunk (\{} -> @A {}) #^^{-1} A#id(5): {} -[[id(5)]]-> ({} -[[8]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt index 5ec8b64c604..79f047465a8 100644 --- a/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -Default has default : {} -> a | a has Default +Default has default : {} -> a | a implements Default -A := {} has [Default {default}] +A := {} implements [Default {default}] default = \{} -> @A {} main = diff --git a/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt b/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt index a0c045ee649..48a4646cf99 100644 --- a/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt +++ b/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt @@ -1,19 +1,19 @@ app "test" provides [main] to "./platform" X has - consume : a -> {} | a has X + consume : a -> {} | a implements X -O := {} has [X {consume: consumeO}] +O := {} implements [X {consume: consumeO}] consumeO = \@O {} -> {} -P := {} has [X {consume: consumeP}] +P := {} implements [X {consume: consumeP}] consumeP = \@P {} -> {} caller = \x -> consume x -# ^ a | a has X -# ^^^^^^^ X#consume(2): a -[[] + a:consume(2):1]-> {} | a has X +# ^ a | a implements X +# ^^^^^^^ X#consume(2): a -[[] + a:consume(2):1]-> {} | a implements X main = { a: caller (@O {}), diff --git a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt index 35e7b3d3624..b904dabe305 100644 --- a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt +++ b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt @@ -1,9 +1,9 @@ app "test" provides [hash] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash -Id := U64 has [MHash {hash}] +Id := U64 implements [MHash {hash}] hash : Id -> U64 #^^^^{-1} Id#hash(3): Id -[[hash(3)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt index ecbe8c29224..19fba98d6f8 100644 --- a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt +++ b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt @@ -1,9 +1,9 @@ app "test" provides [hash] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash -Id := U64 has [MHash {hash}] +Id := U64 implements [MHash {hash}] hash : Id -> U64 hash = \@Id n -> n diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt index cdb461a6f2a..e8f330c0e38 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt @@ -1,8 +1,8 @@ app "test" provides [hashEq] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash -hashEq : a, a -> Bool | a has MHash +hashEq : a, a -> Bool | a implements MHash hashEq = \x, y -> hash x == hash y -#^^^^^^{-1} a, a -[[hashEq(0)]]-> Bool | a has MHash +#^^^^^^{-1} a, a -[[hashEq(0)]]-> Bool | a implements MHash diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt index caf1681ba53..5130b11d449 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt @@ -1,7 +1,7 @@ app "test" provides [hashEq] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash hashEq = \x, y -> hash x == hash y -#^^^^^^{-1} a, a1 -[[hashEq(0)]]-> Bool | a has MHash, a1 has MHash +#^^^^^^{-1} a, a1 -[[hashEq(0)]]-> Bool | a implements MHash, a1 implements MHash diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt index 18d9d568469..30c0829af39 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt @@ -1,11 +1,11 @@ app "test" provides [result] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash hashEq = \x, y -> hash x == hash y -Id := U64 has [MHash {hash}] +Id := U64 implements [MHash {hash}] hash = \@Id n -> n result = hashEq (@Id 100) (@Id 101) diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt index cd2e96ba483..552c80b60b2 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt @@ -1,14 +1,14 @@ app "test" provides [result] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash mulMHashes = \x, y -> hash x * hash y -Id := U64 has [MHash { hash: hashId }] +Id := U64 implements [MHash { hash: hashId }] hashId = \@Id n -> n -Three := {} has [MHash { hash: hashThree }] +Three := {} implements [MHash { hash: hashThree }] hashThree = \@Three _ -> 3 result = mulMHashes (@Id 100) (@Three {}) diff --git a/crates/compiler/uitest/tests/solve/ability_specialization_called.txt b/crates/compiler/uitest/tests/solve/ability_specialization_called.txt index e88496dfdab..20b56e049be 100644 --- a/crates/compiler/uitest/tests/solve/ability_specialization_called.txt +++ b/crates/compiler/uitest/tests/solve/ability_specialization_called.txt @@ -1,9 +1,9 @@ app "test" provides [zero] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash -Id := U64 has [MHash {hash}] +Id := U64 implements [MHash {hash}] hash = \@Id n -> n diff --git a/crates/compiler/uitest/tests/solve/alias_ability_member.txt b/crates/compiler/uitest/tests/solve/alias_ability_member.txt index e552bf692e0..ab5f5d7e9c2 100644 --- a/crates/compiler/uitest/tests/solve/alias_ability_member.txt +++ b/crates/compiler/uitest/tests/solve/alias_ability_member.txt @@ -1,9 +1,9 @@ app "test" provides [thething] to "./platform" -MHash has - hash : a -> U64 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash thething = -#^^^^^^^^{-1} a -[[] + a:hash(2):1]-> U64 | a has MHash +#^^^^^^^^{-1} a -[[] + a:hash(2):1]-> U64 | a implements MHash itis = hash itis diff --git a/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt b/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt index 66960256036..01d4d571873 100644 --- a/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt +++ b/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt @@ -1,8 +1,8 @@ app "test" provides [zeroEncoder] to "./platform" -MEncoder fmt := List U8, fmt -> List U8 | fmt has Format +MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format -Format has it : fmt -> {} | fmt has Format +Format implements it : fmt -> {} | fmt implements Format zeroEncoder = @MEncoder \lst, _ -> lst -#^^^^^^^^^^^{-1} MEncoder a | a has Format +#^^^^^^^^^^^{-1} MEncoder a | a implements Format diff --git a/crates/compiler/uitest/tests/solve/exposed_ability_name.txt b/crates/compiler/uitest/tests/solve/exposed_ability_name.txt index 3563c02521e..875af03cea8 100644 --- a/crates/compiler/uitest/tests/solve/exposed_ability_name.txt +++ b/crates/compiler/uitest/tests/solve/exposed_ability_name.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -MHash has hash : a -> U64 | a has MHash +MHash implements hash : a -> U64 | a implements MHash main = hash -# ^^^^ MHash#hash(2): a -[[] + a:hash(2):1]-> U64 | a has MHash +# ^^^^ MHash#hash(2): a -[[] + a:hash(2):1]-> U64 | a implements MHash diff --git a/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt b/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt index d124bd1687a..b572ce562ca 100644 --- a/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt +++ b/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt @@ -1,14 +1,14 @@ app "test" provides [hash, hash32, eq, le] to "./platform" -MHash has - hash : a -> U64 | a has MHash - hash32 : a -> U32 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash + hash32 : a -> U32 | a implements MHash -Ord has - eq : a, a -> Bool | a has Ord - le : a, a -> Bool | a has Ord +Ord implements + eq : a, a -> Bool | a implements Ord + le : a, a -> Bool | a implements Ord -Id := U64 has [MHash {hash, hash32}, Ord {eq, le}] +Id := U64 implements [MHash {hash, hash32}, Ord {eq, le}] hash = \@Id n -> n #^^^^{-1} Id#hash(7): Id -[[hash(7)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt b/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt index 7b73ffa9ff0..37b18653c07 100644 --- a/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt +++ b/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt @@ -1,10 +1,10 @@ app "test" provides [hash, hash32] to "./platform" -MHash has - hash : a -> U64 | a has MHash - hash32 : a -> U32 | a has MHash +MHash implements + hash : a -> U64 | a implements MHash + hash32 : a -> U32 | a implements MHash -Id := U64 has [MHash {hash, hash32}] +Id := U64 implements [MHash {hash, hash32}] hash = \@Id n -> n #^^^^{-1} Id#hash(4): Id -[[hash(4)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt b/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt index 33e30ed9718..190a4d2701b 100644 --- a/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt +++ b/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt @@ -1,8 +1,8 @@ app "test" provides [hash] to "./platform" -MHash has hash : a -> U64 | a has MHash +MHash implements hash : a -> U64 | a implements MHash -Id := U64 has [MHash {hash}] +Id := U64 implements [MHash {hash}] hash = \@Id n -> n #^^^^{-1} Id#hash(3): Id -[[hash(3)]]-> U64 diff --git a/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt b/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt index dfba0f19d6a..5a0ec296974 100644 --- a/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt +++ b/crates/compiler/uitest/tests/solve/stdlib_encode_json.txt @@ -2,7 +2,7 @@ app "test" imports [Json] provides [main] to "./platform" -HelloWorld := {} has [Encoding {toEncoder}] +HelloWorld := {} implements [Encoding {toEncoder}] toEncoder = \@HelloWorld {} -> Encode.custom \bytes, fmt -> diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 0bfef5101cf..a983adc8bc4 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -8830,7 +8830,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash] to "./platform" - MHash has + MHash implements hash : a -> U64 | a implements MHash Id := U64 implements [MHash {hash}] @@ -8864,7 +8864,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [noGoodVeryBadTerrible] to "./platform" - MHash has + MHash implements hash : a -> U64 | a implements MHash Id := U64 implements [MHash {hash}] @@ -8912,7 +8912,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [main] to "./platform" main = - MHash has + MHash implements hash : a -> U64 | a implements MHash 123 @@ -8923,7 +8923,7 @@ In roc, functions are always written as a lambda, like{} This ability definition is not on the top-level of a module: - 4│> MHash has + 4│> MHash implements 5│> hash : a -> U64 | a implements MHash Abilities can only be defined on the top-level of a Roc module. @@ -8936,7 +8936,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash, hashable] to "./platform" - MHash has + MHash implements hash : a -> U64 | a implements MHash Id := U64 implements [MHash {hash}] @@ -8977,7 +8977,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [result] to "./platform" - MHash has + MHash implements hash : a -> U64 | a implements MHash mulMHashes : MHash, MHash -> U64 From dbc02045324f2681915beade9decab0dfc962326 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 21:30:16 -0400 Subject: [PATCH 27/55] abilities syntax `has` -> `implements` --- .../cli_testing_examples/benchmarks/AStar.roc | 12 ++-- crates/compiler/can/src/abilities.rs | 8 +-- crates/compiler/can/src/annotation.rs | 2 +- crates/compiler/can/src/def.rs | 14 ++-- crates/compiler/can/src/pattern.rs | 2 +- crates/compiler/can/src/scope.rs | 2 +- crates/compiler/derive/src/decoding.rs | 8 +-- crates/compiler/derive/src/decoding/list.rs | 10 +-- crates/compiler/derive/src/decoding/record.rs | 2 +- crates/compiler/derive/src/decoding/tuple.rs | 2 +- crates/compiler/derive/src/encoding.rs | 66 +++++++++---------- crates/compiler/derive/src/hash.rs | 14 ++-- crates/compiler/derive/src/util.rs | 2 +- crates/compiler/fmt/src/annotation.rs | 2 +- crates/compiler/gen_wasm/src/backend.rs | 9 ++- crates/compiler/load_internal/src/file.rs | 6 +- crates/compiler/solve/src/ability.rs | 2 +- crates/compiler/solve/src/solve.rs | 2 +- crates/compiler/types/src/pretty_print.rs | 4 +- crates/compiler/types/src/types.rs | 2 +- crates/compiler/unify/src/unify.rs | 2 +- 21 files changed, 89 insertions(+), 84 deletions(-) diff --git a/crates/cli_testing_examples/benchmarks/AStar.roc b/crates/cli_testing_examples/benchmarks/AStar.roc index 2021ac18777..95edcc7bc4a 100644 --- a/crates/cli_testing_examples/benchmarks/AStar.roc +++ b/crates/cli_testing_examples/benchmarks/AStar.roc @@ -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 {} diff --git a/crates/compiler/can/src/abilities.rs b/crates/compiler/can/src/abilities.rs index f5f056ebcb8..4766b7eb7d9 100644 --- a/crates/compiler/can/src/abilities.rs +++ b/crates/compiler/can/src/abilities.rs @@ -80,7 +80,7 @@ impl AbilityMemberData { /// 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 { /// /// 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 IAbilitiesStore { } /// 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 { /// 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( diff --git a/crates/compiler/can/src/annotation.rs b/crates/compiler/can/src/annotation.rs index 63e9b8ef340..7906ccb5e62 100644 --- a/crates/compiler/can/src/annotation.rs +++ b/crates/compiler/can/src/annotation.rs @@ -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( diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 41d4800cfb6..65ff7dc40b7 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -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( diff --git a/crates/compiler/can/src/pattern.rs b/crates/compiler/can/src/pattern.rs index d881ad4257c..5541ab47106 100644 --- a/crates/compiler/can/src/pattern.rs +++ b/crates/compiler/can/src/pattern.rs @@ -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 { diff --git a/crates/compiler/can/src/scope.rs b/crates/compiler/can/src/scope.rs index d1f4656ba7a..9c2cf0aa757 100644 --- a/crates/compiler/can/src/scope.rs +++ b/crates/compiler/can/src/scope.rs @@ -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. diff --git a/crates/compiler/derive/src/decoding.rs b/crates/compiler/derive/src/decoding.rs index 2ba0b8cff8f..acd58680b25 100644 --- a/crates/compiler/derive/src/decoding.rs +++ b/crates/compiler/derive/src/decoding.rs @@ -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); diff --git a/crates/compiler/derive/src/decoding/list.rs b/crates/compiler/derive/src/decoding/list.rs index 53c89fd1bd0..924c8047ec0 100644 --- a/crates/compiler/derive/src/decoding/list.rs +++ b/crates/compiler/derive/src/decoding/list.rs @@ -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); diff --git a/crates/compiler/derive/src/decoding/record.rs b/crates/compiler/derive/src/decoding/record.rs index d62ffe2f907..8549df9f7d8 100644 --- a/crates/compiler/derive/src/decoding/record.rs +++ b/crates/compiler/derive/src/decoding/record.rs @@ -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} diff --git a/crates/compiler/derive/src/decoding/tuple.rs b/crates/compiler/derive/src/decoding/tuple.rs index b6ce2016911..15e9666427f 100644 --- a/crates/compiler/derive/src/decoding/tuple.rs +++ b/crates/compiler/derive/src/decoding/tuple.rs @@ -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} diff --git a/crates/compiler/derive/src/encoding.rs b/crates/compiler/derive/src/encoding.rs index 4073e960a93..959d8a8a43e 100644 --- a/crates/compiler/derive/src/encoding.rs +++ b/crates/compiler/derive/src/encoding.rs @@ -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)), diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index f01a28eac21..aa122c47d6c 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -75,7 +75,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (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, diff --git a/crates/compiler/derive/src/util.rs b/crates/compiler/derive/src/util.rs index 2319dd2e12f..1dfc38f89fd 100644 --- a/crates/compiler/derive/src/util.rs +++ b/crates/compiler/derive/src/util.rs @@ -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! // diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 7b6c969dadf..02f5f58e101 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -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 } diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index bc4277aec69..720f500d11c 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -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, .. } => { diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 6bd32895250..0f3814687b7 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -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()); diff --git a/crates/compiler/solve/src/ability.rs b/crates/compiler/solve/src/ability.rs index 47d0ba15a3d..633cdc31104 100644 --- a/crates/compiler/solve/src/ability.rs +++ b/crates/compiler/solve/src/ability.rs @@ -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); } } diff --git a/crates/compiler/solve/src/solve.rs b/crates/compiler/solve/src/solve.rs index ba319525376..72d1d3bfef4 100644 --- a/crates/compiler/solve/src/solve.rs +++ b/crates/compiler/solve/src/solve.rs @@ -2510,7 +2510,7 @@ impl AmbientFunctionPolicy { }), Content::FlexVar(_) => { // Something like - // Encoder fmt : List U8, fmt -a-> List U8 | fmt has EncoderFormatting + // Encoder fmt : 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 { diff --git a/crates/compiler/types/src/pretty_print.rs b/crates/compiler/types/src/pretty_print.rs index 77bbbb4da18..8e6d41d0316 100644 --- a/crates/compiler/types/src/pretty_print.rs +++ b/crates/compiler/types/src/pretty_print.rs @@ -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 { diff --git a/crates/compiler/types/src/types.rs b/crates/compiler/types/src/types.rs index 00eb2b0098d..8d668e8207a 100644 --- a/crates/compiler/types/src/types.rs +++ b/crates/compiler/types/src/types.rs @@ -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 diff --git a/crates/compiler/unify/src/unify.rs b/crates/compiler/unify/src/unify.rs index 383197a8056..98a8aa1149c 100644 --- a/crates/compiler/unify/src/unify.rs +++ b/crates/compiler/unify/src/unify.rs @@ -1302,7 +1302,7 @@ fn extract_specialization_lambda_set( // 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 // From 3b1dbafb2ecf22dba624bdbdcbab759a67bc2fc4 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Wed, 24 May 2023 21:30:35 -0400 Subject: [PATCH 28/55] abilities syntax `has` -> `implements` in examples --- examples/cli/cli-platform/Env.roc | 4 ++-- examples/cli/cli-platform/EnvDecoding.roc | 2 +- examples/cli/cli-platform/File.roc | 4 ++-- examples/cli/cli-platform/Http.roc | 2 +- examples/python-interop/platform/main.roc | 2 +- examples/ruby-interop/platform/main.roc | 2 +- .../virtual-dom-wip/platform/Html/Internal/Client.roc | 8 ++++---- .../virtual-dom-wip/platform/Html/Internal/Server.roc | 4 ++-- examples/virtual-dom-wip/platform/client-side.roc | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/cli/cli-platform/Env.roc b/examples/cli/cli-platform/Env.roc index 2826d34941b..061ab69b28b 100644 --- a/examples/cli/cli-platform/Env.roc +++ b/examples/cli/cli-platform/Env.roc @@ -65,7 +65,7 @@ var = \name -> ## - comma-separated lists (of either strings or numbers), as long as there are no spaces after the commas ## ## Trying to decode into any other types will always fail with a `DecodeErr`. -decode : Str -> Task val [VarNotFound, DecodeErr DecodeError] | val has Decoding +decode : Str -> Task val [VarNotFound, DecodeErr DecodeError] | val implements Decoding decode = \name -> Effect.envVar name |> Effect.map @@ -120,4 +120,4 @@ dict = # decode all the required vars only, and then decode the optional ones separately some other way. # Alternatively, it could make sense to have some sort of tag union convention here, e.g. # if decoding into a tag union of [Present val, Missing], then it knows what to do. -# decodeAll : Task val [] [EnvDecodingFailed Str] [Env] | val has Decoding +# decodeAll : Task val [] [EnvDecodingFailed Str] [Env] | val implements Decoding diff --git a/examples/cli/cli-platform/EnvDecoding.roc b/examples/cli/cli-platform/EnvDecoding.roc index ccc4a9f2bb6..463c4ca58ae 100644 --- a/examples/cli/cli-platform/EnvDecoding.roc +++ b/examples/cli/cli-platform/EnvDecoding.roc @@ -1,6 +1,6 @@ interface EnvDecoding exposes [EnvFormat, format] imports [] -EnvFormat := {} has [ +EnvFormat := {} implements [ DecoderFormatting { u8: envU8, u16: envU16, diff --git a/examples/cli/cli-platform/File.roc b/examples/cli/cli-platform/File.roc index 708fe1b7a64..9d91c6d7c84 100644 --- a/examples/cli/cli-platform/File.roc +++ b/examples/cli/cli-platform/File.roc @@ -26,7 +26,7 @@ WriteErr : InternalFile.WriteErr ## This opens the file first and closes it after writing to it. ## ## To write unformatted bytes to a file, you can use [File.writeBytes] instead. -write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] | val has Encode.Encoding, fmt has Encode.EncoderFormatting +write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] | val has Encode.Encoding, fmt implements Encode.EncoderFormatting write = \path, val, fmt -> bytes = Encode.toBytes val fmt @@ -119,7 +119,7 @@ readUtf8 = \path -> # Str # [FileReadErr Path ReadErr, FileReadDecodeErr Path [Leftover (List U8)]Decode.DecodeError ] # [Read [File]] -# | val has Decode.Decoding, fmt has Decode.DecoderFormatting +# | val has Decode.Decoding, fmt implements Decode.DecoderFormatting # read = \path, fmt -> # effect = Effect.map (Effect.fileReadBytes (InternalPath.toBytes path)) \result -> # when result is diff --git a/examples/cli/cli-platform/Http.roc b/examples/cli/cli-platform/Http.roc index 4e39bad4192..372d10a4816 100644 --- a/examples/cli/cli-platform/Http.roc +++ b/examples/cli/cli-platform/Http.roc @@ -56,7 +56,7 @@ stringBody : [MimeType Str], Str -> Body stringBody = \mimeType, str -> Body mimeType (Str.toUtf8 str) -# jsonBody : a -> Body | a has Encoding +# jsonBody : a -> Body | a implements Encoding # jsonBody = \val -> # Body (MimeType "application/json") (Encode.toBytes val Json.format) # diff --git a/examples/python-interop/platform/main.roc b/examples/python-interop/platform/main.roc index fb0832772fe..3d9f16bbb2d 100644 --- a/examples/python-interop/platform/main.roc +++ b/examples/python-interop/platform/main.roc @@ -1,5 +1,5 @@ platform "python-interop" - requires {} { main : arg -> ret | arg has Decoding, ret has Encoding } + requires {} { main : arg -> ret | arg has Decoding, ret implements Encoding } exposes [] packages {} imports [Json] diff --git a/examples/ruby-interop/platform/main.roc b/examples/ruby-interop/platform/main.roc index 96500cb448a..07c6284f422 100644 --- a/examples/ruby-interop/platform/main.roc +++ b/examples/ruby-interop/platform/main.roc @@ -1,5 +1,5 @@ platform "ruby-interop" - requires {} { main : arg -> ret | arg has Decoding, ret has Encoding } + requires {} { main : arg -> ret | arg has Decoding, ret implements Encoding } exposes [] packages {} imports [Json] diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc index c69ed2ce672..c8bc2f1b082 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc @@ -84,7 +84,7 @@ DiffState state : { rendered : RenderedTree state, patches : List Patch } # ------------------------------- # INITIALISATION # ------------------------------- -initClientApp : List U8, App state initData -> Effect (PlatformState state initData) | initData has Decoding +initClientApp : List U8, App state initData -> Effect (PlatformState state initData) | initData implements Decoding initClientApp = \json, app -> # Initialise the Roc representation of the rendered DOM, and calculate patches (for event listeners) { state, rendered, patches } = @@ -100,7 +100,7 @@ initClientApp = \json, app -> } # Testable helper function to initialise the app -initClientAppHelp : List U8, App state initData -> { state, rendered : RenderedTree state, patches : List Patch } | initData has Decoding +initClientAppHelp : List U8, App state initData -> { state, rendered : RenderedTree state, patches : List Patch } | initData implements Decoding initClientAppHelp = \json, app -> state = json @@ -200,7 +200,7 @@ JsEventResult state initData : { } ## Dispatch a JavaScript event to a Roc handler, given the handler ID and some JSON event data. -dispatchEvent : PlatformState state initData, List (List U8), HandlerId -> Effect (JsEventResult state initData) | initData has Decoding +dispatchEvent : PlatformState state initData, List (List U8), HandlerId -> Effect (JsEventResult state initData) | initData implements Decoding dispatchEvent = \platformState, eventData, handlerId -> { app, state, rendered } = platformState @@ -694,7 +694,7 @@ eqRenderedAttrs = \a, b -> && eqAttrDict a.domProps b.domProps && eqAttrDict a.styles b.styles -eqAttrDict : Dict Str v, Dict Str v -> Bool | v has Eq +eqAttrDict : Dict Str v, Dict Str v -> Bool | v implements Eq eqAttrDict = \a, b -> Dict.keys a |> List.all \k -> Dict.get a k == Dict.get b k diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Server.roc b/examples/virtual-dom-wip/platform/Html/Internal/Server.roc index be871396d1a..05f1493d110 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Server.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Server.roc @@ -57,7 +57,7 @@ appendRenderedStaticAttr = \{ buffer, styles }, attr -> # ------------------------------- # INITIALISATION # ------------------------------- -initServerApp : App state initData, initData, Str -> Result (Html []) [InvalidDocument] | initData has Encoding +initServerApp : App state initData, initData, Str -> Result (Html []) [InvalidDocument] | initData implements Encoding initServerApp = \app, initData, hostJavaScript -> initData |> Ok @@ -66,7 +66,7 @@ initServerApp = \app, initData, hostJavaScript -> |> translateStatic |> insertRocScript initData app.wasmUrl hostJavaScript -insertRocScript : Html [], initData, Str, Str -> Result (Html []) [InvalidDocument] | initData has Encoding +insertRocScript : Html [], initData, Str, Str -> Result (Html []) [InvalidDocument] | initData implements Encoding insertRocScript = \document, initData, wasmUrl, hostJavaScript -> encode = \value -> diff --git a/examples/virtual-dom-wip/platform/client-side.roc b/examples/virtual-dom-wip/platform/client-side.roc index 02bf4f75597..73e8603f53f 100644 --- a/examples/virtual-dom-wip/platform/client-side.roc +++ b/examples/virtual-dom-wip/platform/client-side.roc @@ -26,7 +26,7 @@ ToHost state initData : { } # TODO: naming the type variables causes a type 'mismatch' -# main : FromHost state initData -> Effect (ToHost state initData) | initData has Decoding & Encoding +# main : FromHost state initData -> Effect (ToHost state initData) | initData implements Decoding & Encoding main : FromHost _ _ -> Effect (ToHost _ _) main = \fromHost -> if fromHost.isInitEvent then From d97d0c54830f18857a8dc4c987d3a277375e437f Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 20:35:35 -0400 Subject: [PATCH 29/55] Re-enable test --- crates/cli/tests/cli_run.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 60729b4b10b..21a17eda785 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -634,7 +634,6 @@ mod cli_run { } #[test] - #[ignore] #[cfg_attr( windows, ignore = "this platform is broken, and `roc run --lib` is missing on windows" From 33c2b9dfddc6cf49b729b7540eb1d3144c2d1d3a Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 20:37:02 -0400 Subject: [PATCH 30/55] has -> implements in comments --- crates/compiler/can/src/def.rs | 2 +- crates/compiler/derive/src/decoding/list.rs | 6 +++--- crates/compiler/derive/src/hash.rs | 6 +++--- crates/compiler/load_internal/src/docs.rs | 2 +- crates/compiler/load_internal/src/file.rs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 65ff7dc40b7..94719ade9e4 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -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 implements Eq + // Eq has eq : a, b -> Bool | a implements 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( diff --git a/crates/compiler/derive/src/decoding/list.rs b/crates/compiler/derive/src/decoding/list.rs index 924c8047ec0..59fe3e091bf 100644 --- a/crates/compiler/derive/src/decoding/list.rs +++ b/crates/compiler/derive/src/decoding/list.rs @@ -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 implements DecoderFormatting + // def_symbol : Decoder (List elem) fmt | elem implements 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 implements EncoderFormatting + // Decode.decoder : Decoder elem fmt | elem implements Decoding, fmt implements EncoderFormatting let (elem_decoder, elem_decoder_var) = { // build `Decode.decoder : Decoder elem fmt` type - // Decoder val fmt | val has Decoding, fmt implements EncoderFormatting + // Decoder val fmt | val implements Decoding, fmt implements EncoderFormatting let elem_decoder_var = env.import_builtin_symbol_var(Symbol::DECODE_DECODER); // set val ~ elem diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index aa122c47d6c..d0fff82ceed 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -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 implements Hash + // hasher, val -[uls]-> hasher | hasher implements 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 implements Hash + // hasher, val -[uls]-> hasher | hasher implements 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) implements Hash + // Hash.hash : hasher, (typeof field) -[clos]-> hasher | hasher implements 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, diff --git a/crates/compiler/load_internal/src/docs.rs b/crates/compiler/load_internal/src/docs.rs index f74667f9360..55db7563b38 100644 --- a/crates/compiler/load_internal/src/docs.rs +++ b/crates/compiler/load_internal/src/docs.rs @@ -450,7 +450,7 @@ fn contains_unexposed_type( false } Where(loc_ann, _loc_has_clauses) => { - // We assume all the abilities in the `has` clause are from exported modules. + // We assume all the abilities in the `implements` clause are from exported modules. // TODO don't assume this! Instead, look them up and verify. contains_unexposed_type(&loc_ann.value, exposed_module_ids, module_ids) } diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 0f3814687b7..9bb89659937 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -3172,7 +3172,7 @@ fn update<'a>( // # Default module // interface Default exposes [default, getDefault] // - // Default has default : {} -> a | a implements Default + // Default implements default : {} -> a | a implements Default // // getDefault = \{} -> default {} // From 58a84fdc29b0aa3206d6f5ed46ace77db496bbaf Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 20:37:42 -0400 Subject: [PATCH 31/55] has -> implements in tests --- crates/compiler/test_derive/src/decoding.rs | 12 +++---- crates/compiler/test_derive/src/encoding.rs | 38 ++++++++++----------- crates/compiler/test_derive/src/hash.rs | 24 ++++++------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/crates/compiler/test_derive/src/decoding.rs b/crates/compiler/test_derive/src/decoding.rs index de6695380a1..d77a3b396f0 100644 --- a/crates/compiler/test_derive/src/decoding.rs +++ b/crates/compiler/test_derive/src/decoding.rs @@ -106,8 +106,8 @@ fn list() { derive_test(Decoder, v!(Symbol::LIST_LIST v!(STR)), |golden| { assert_snapshot!(golden, @r###" # derived for List Str - # Decoder (List val) fmt | fmt has DecoderFormatting, val implements Decoding - # List U8, fmt -[[custom(3)]]-> { rest : List U8, result : [Err [TooShort], Ok (List val)] } | fmt has DecoderFormatting, val implements Decoding + # Decoder (List val) fmt | fmt implements DecoderFormatting, val implements Decoding + # List U8, fmt -[[custom(3)]]-> { rest : List U8, result : [Err [TooShort], Ok (List val)] } | fmt implements DecoderFormatting, val implements Decoding # Specialization lambda sets: # @<1>: [[custom(3)]] #Derived.decoder_list = @@ -124,8 +124,8 @@ fn record_2_fields() { derive_test(Decoder, v!({first: v!(STR), second: v!(STR),}), |golden| { assert_snapshot!(golden, @r###" # derived for { first : Str, second : Str } - # Decoder { first : val, second : val1 } fmt | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding + # Decoder { first : val, second : val1 } fmt | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_{first,second} = @@ -181,8 +181,8 @@ fn tuple_2_fields() { derive_test(Decoder, v!((v!(STR), v!(U8),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( Str, U8 )* - # Decoder ( val, val1 )* fmt | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt has DecoderFormatting, val has Decoding, val1 implements Decoding + # Decoder ( val, val1 )* fmt | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_(arity:2) = diff --git a/crates/compiler/test_derive/src/encoding.rs b/crates/compiler/test_derive/src/encoding.rs index b726cd5930c..1bf376ec25b 100644 --- a/crates/compiler/test_derive/src/encoding.rs +++ b/crates/compiler/test_derive/src/encoding.rs @@ -228,8 +228,8 @@ fn one_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8 } - # { a : val } -[[toEncoder_{a}(0)]]-> Encoder fmt | fmt has EncoderFormatting, val implements Encoding - # { a : val } -[[toEncoder_{a}(0)]]-> (List U8, fmt -[[custom(2) { a : val }]]-> List U8) | fmt has EncoderFormatting, val implements Encoding + # { a : val } -[[toEncoder_{a}(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding + # { a : val } -[[toEncoder_{a}(0)]]-> (List U8, fmt -[[custom(2) { a : val }]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a}(0)]] # @<2>: [[custom(2) { a : val }]] | val implements Encoding @@ -251,11 +251,11 @@ fn two_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a,b}(0)]] - # @<2>: [[custom(2) { a : val, b : val1 }]] | val has Encoding, val1 implements Encoding + # @<2>: [[custom(2) { a : val, b : val1 }]] | val implements Encoding, val1 implements Encoding #Derived.toEncoder_{a,b} = \#Derived.rcd -> custom @@ -278,11 +278,11 @@ fn two_field_tuple() { derive_test(ToEncoder, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding - # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_(arity:2)(0)]] - # @<2>: [[custom(2) ( val, val1 )*]] | val has Encoding, val1 implements Encoding + # @<2>: [[custom(2) ( val, val1 )*]] | val implements Encoding, val1 implements Encoding #Derived.toEncoder_(arity:2) = \#Derived.tup -> custom @@ -338,11 +338,11 @@ fn tag_one_label_two_args() { derive_test(ToEncoder, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding - # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 2](0)]] - # @<2>: [[custom(4) [A val val1]]] | val has Encoding, val1 implements Encoding + # @<2>: [[custom(4) [A val val1]]] | val implements Encoding, val1 implements Encoding #Derived.toEncoder_[A 2] = \#Derived.tag -> custom @@ -366,11 +366,11 @@ fn tag_two_labels() { |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 3,B 1](0)]] - # @<2>: [[custom(6) [A val val1 val1, B val1]]] | val has Encoding, val1 implements Encoding + # @<2>: [[custom(6) [A val val1 val1, B val1]]] | val implements Encoding, val1 implements Encoding #Derived.toEncoder_[A 3,B 1] = \#Derived.tag -> custom @@ -402,11 +402,11 @@ fn recursive_tag_union() { |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt has EncoderFormatting, val has Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[Cons 2,Nil 0](0)]] - # @<2>: [[custom(4) [Cons val val1, Nil]]] | val has Encoding, val1 implements Encoding + # @<2>: [[custom(4) [Cons val val1, Nil]]] | val implements Encoding, val1 implements Encoding #Derived.toEncoder_[Cons 2,Nil 0] = \#Derived.tag -> custom @@ -429,8 +429,8 @@ fn list() { derive_test(ToEncoder, v!(Symbol::LIST_LIST v!(STR)), |golden| { assert_snapshot!(golden, @r###" # derived for List Str - # List val -[[toEncoder_list(0)]]-> Encoder fmt | fmt has EncoderFormatting, val implements Encoding - # List val -[[toEncoder_list(0)]]-> (List U8, fmt -[[custom(4) (List val)]]-> List U8) | fmt has EncoderFormatting, val implements Encoding + # List val -[[toEncoder_list(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding + # List val -[[toEncoder_list(0)]]-> (List U8, fmt -[[custom(4) (List val)]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_list(0)]] # @<2>: [[custom(4) (List val)]] | val implements Encoding diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index 669fb37d25a..a13fc7187bd 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -181,8 +181,8 @@ fn one_field_record() { derive_test(Hash, v!({ a: v!(U8), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8 } - # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher implements Hasher - # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher implements Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a implements Hash, hasher implements Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a}(0)]] #Derived.hash_{a} = @@ -197,8 +197,8 @@ fn two_field_record() { derive_test(Hash, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a,b}(0)]] #Derived.hash_{a,b} = @@ -214,8 +214,8 @@ fn two_element_tuple() { derive_test(Hash, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_(arity:2)(0)]] #Derived.hash_(arity:2) = @@ -246,8 +246,8 @@ fn tag_one_label_newtype() { derive_test(Hash, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a has Hash, a1 has Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 2](0)]] #Derived.hash_[A 2] = @@ -263,8 +263,8 @@ fn tag_two_labels() { derive_test(Hash, v!([A v!(U8) v!(STR) v!(U16), B v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash, a3 implements Hash - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a has Hasher, a1 has Hash, a2 has Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 has Hash, a2 has Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 has Hash, a2 has Hash, a3 implements Hash # Specialization lambda sets: # @<1>: [[hash_[A 3,B 1](0)]] #Derived.hash_[A 3,B 1] = @@ -304,8 +304,8 @@ fn recursive_tag_union() { derive_test(Hash, v!([Nil, Cons v!(U8) v!(^lst) ] as lst), |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a has Hasher, a1 has Hash, a2 implements Hash - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a has Hasher, a1 has Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 has Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 has Hash, a2 implements Hash # Specialization lambda sets: # @<1>: [[hash_[Cons 2,Nil 0](0)]] #Derived.hash_[Cons 2,Nil 0] = From c68807bc5aedb91dd846928d1e73c4884ad65844 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 20:39:01 -0400 Subject: [PATCH 32/55] has -> implements in roc code --- ...use_multiple_has_across_newlines.expr.formatted.roc | 2 +- crates/compiler/uitest/tests/ability/smoke/decoder.txt | 4 ++-- crates/compiler/uitest/tests/ability/smoke/encoder.txt | 4 ++-- .../polymorphic_lambda_set_specialization.txt | 2 +- ...ymorphic_lambda_set_specialization_bound_output.txt | 2 +- ...t_specialization_branching_over_single_variable.txt | 4 ++-- ..._specialization_varying_over_multiple_variables.txt | 10 +++++----- ...ion_varying_over_multiple_variables_two_results.txt | 10 +++++----- ...ialization_with_deep_specialization_and_capture.txt | 2 +- ...hic_lambda_set_specialization_with_let_weakened.txt | 2 +- ..._set_specialization_with_let_weakened_unapplied.txt | 2 +- examples/cli/cli-platform/File.roc | 4 ++-- examples/python-interop/platform/main.roc | 2 +- examples/ruby-interop/platform/main.roc | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc index 1e2868883eb..0ebb9de5a06 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a has Hash, b has Eq, c implements Ord +f : a -> (b -> c) | a implements Hash, b has Eq, c implements Ord f \ No newline at end of file diff --git a/crates/compiler/uitest/tests/ability/smoke/decoder.txt b/crates/compiler/uitest/tests/ability/smoke/decoder.txt index 987ba167340..77546828dd9 100644 --- a/crates/compiler/uitest/tests/ability/smoke/decoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/decoder.txt @@ -5,7 +5,7 @@ MDecodeError : [TooShort, Leftover (List U8)] MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting MDecoding has - decoder : MDecoder val fmt | val has MDecoding, fmt implements MDecoderFormatting + decoder : MDecoder val fmt | val implements MDecoding, fmt implements MDecoderFormatting MDecoderFormatting has u8 : MDecoder U8 fmt | fmt implements MDecoderFormatting @@ -14,7 +14,7 @@ decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError decodeWith = \lst, (@MDecoder doDecode), fmt -> doDecode lst fmt fromBytes : List U8, fmt -> Result val MDecodeError - | fmt has MDecoderFormatting, val implements MDecoding + | fmt implements MDecoderFormatting, val implements MDecoding fromBytes = \lst, fmt -> when decodeWith lst decoder fmt is { result, rest } -> diff --git a/crates/compiler/uitest/tests/ability/smoke/encoder.txt b/crates/compiler/uitest/tests/ability/smoke/encoder.txt index a4a74c6822d..f22517fb13f 100644 --- a/crates/compiler/uitest/tests/ability/smoke/encoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/encoder.txt @@ -3,7 +3,7 @@ app "test" provides [myU8Bytes] to "./platform" MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format MEncoding has - toEncoder : val -> MEncoder fmt | val has MEncoding, fmt implements Format + toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format Format has u8 : U8 -> MEncoder fmt | fmt implements Format @@ -11,7 +11,7 @@ Format has appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt implements Format appendWith = \lst, (@MEncoder doFormat), fmt -> doFormat lst fmt -toBytes : val, fmt -> List U8 | val has MEncoding, fmt implements Format +toBytes : val, fmt -> List U8 | val implements MEncoding, fmt implements Format toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt index dfe79b44ae1..333219f2a80 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a has F, b implements G +F has f : a -> (b -> {}) | a implements F, b implements G G has g : b -> {} | b implements G Fo := {} implements [F {f}] diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt index 45a01d058d8..ed7cc865d3a 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -F has f : a -> ({} -> b) | a has F, b implements G +F has f : a -> ({} -> b) | a implements F, b implements G G has g : {} -> b | b implements G Fo := {} implements [F {f}] diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt index 8b7e092a806..951c75103cd 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt @@ -1,6 +1,6 @@ app "test" provides [f] to "./platform" -J has j : j -> (k -> {}) | j has J, k implements K +J has j : j -> (k -> {}) | j implements J, k implements K K has k : k -> {} | k implements K C := {} implements [J {j: jC}] @@ -19,4 +19,4 @@ f = \flag, a, c -> B -> j a it c # ^ k | k implements K -# ^^ k -[[] + j:j(2):2]-> {} | j has J, k implements K +# ^^ k -[[] + j:j(2):2]-> {} | j implements J, k implements K diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt index 0209cfbdb01..323d607f776 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) | j has J, k implements K +J has j : j -> (k -> {}) | j implements J, k implements K K has k : k -> {} | k implements K C := {} implements [J {j: jC}] @@ -19,14 +19,14 @@ f = \flag, a, b -> # ^ j | j implements J # ^ j | j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j has J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j implements J, j1 has J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j implements J, j1 has J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K main = (f A (@C {}) (@D {})) (@E {}) # ^ [A, B], C, D -[[f(11)]]-> (E -[[k(10)]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt index 4a1dd5f38af..a6f436e4b11 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) | j has J, k implements K +J has j : j -> (k -> {}) | j implements J, k implements K K has k : k -> {} | k implements K C := {} implements [J {j: jC}] @@ -23,14 +23,14 @@ f = \flag, a, b -> # ^ j | j implements J # ^ j | j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j has J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j implements J, j1 has J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j implements J, j1 has J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K main = #^^^^{-1} {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt index 3c155d1173e..6c83ef6b6ae 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -F has f : a, b -> ({} -> ({} -> {})) | a has F, b implements G +F has f : a, b -> ({} -> ({} -> {})) | a implements F, b implements G G has g : b -> ({} -> {}) | b implements G Fo := {} implements [F {f}] diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt index 8f3d9427b97..618d29dcc33 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a has F, b implements G +F has f : a -> (b -> {}) | a implements F, b implements G G has g : b -> {} | b implements G Fo := {} implements [F {f}] diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt index 6a159a5e62d..71dc02b2cca 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a has F, b implements G +F has f : a -> (b -> {}) | a implements F, b implements G G has g : b -> {} | b implements G Fo := {} implements [F {f}] diff --git a/examples/cli/cli-platform/File.roc b/examples/cli/cli-platform/File.roc index 9d91c6d7c84..97d8841792f 100644 --- a/examples/cli/cli-platform/File.roc +++ b/examples/cli/cli-platform/File.roc @@ -26,7 +26,7 @@ WriteErr : InternalFile.WriteErr ## This opens the file first and closes it after writing to it. ## ## To write unformatted bytes to a file, you can use [File.writeBytes] instead. -write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] | val has Encode.Encoding, fmt implements Encode.EncoderFormatting +write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] | val implements Encode.Encoding, fmt implements Encode.EncoderFormatting write = \path, val, fmt -> bytes = Encode.toBytes val fmt @@ -119,7 +119,7 @@ readUtf8 = \path -> # Str # [FileReadErr Path ReadErr, FileReadDecodeErr Path [Leftover (List U8)]Decode.DecodeError ] # [Read [File]] -# | val has Decode.Decoding, fmt implements Decode.DecoderFormatting +# | val implements Decode.Decoding, fmt implements Decode.DecoderFormatting # read = \path, fmt -> # effect = Effect.map (Effect.fileReadBytes (InternalPath.toBytes path)) \result -> # when result is diff --git a/examples/python-interop/platform/main.roc b/examples/python-interop/platform/main.roc index 3d9f16bbb2d..949cbe8dd24 100644 --- a/examples/python-interop/platform/main.roc +++ b/examples/python-interop/platform/main.roc @@ -1,5 +1,5 @@ platform "python-interop" - requires {} { main : arg -> ret | arg has Decoding, ret implements Encoding } + requires {} { main : arg -> ret | arg implements Decoding, ret implements Encoding } exposes [] packages {} imports [Json] diff --git a/examples/ruby-interop/platform/main.roc b/examples/ruby-interop/platform/main.roc index 07c6284f422..1cae530d890 100644 --- a/examples/ruby-interop/platform/main.roc +++ b/examples/ruby-interop/platform/main.roc @@ -1,5 +1,5 @@ platform "ruby-interop" - requires {} { main : arg -> ret | arg has Decoding, ret implements Encoding } + requires {} { main : arg -> ret | arg implements Decoding, ret implements Encoding } exposes [] packages {} imports [Json] From d3f6277ea31bb73811372aa1551081577178c5e0 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 22:59:11 -0400 Subject: [PATCH 33/55] has -> implements in comments --- crates/compiler/can/src/abilities.rs | 8 ++++---- crates/compiler/can/src/annotation.rs | 4 ++-- crates/compiler/can/src/def.rs | 4 ++-- crates/compiler/can/src/scope.rs | 2 +- crates/compiler/can/src/traverse.rs | 2 +- crates/compiler/types/src/subs.rs | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/compiler/can/src/abilities.rs b/crates/compiler/can/src/abilities.rs index 4766b7eb7d9..7f77c01bbaa 100644 --- a/crates/compiler/can/src/abilities.rs +++ b/crates/compiler/can/src/abilities.rs @@ -80,7 +80,7 @@ impl AbilityMemberData { /// Solved lambda sets for an ability member specialization. For example, if we have /// -/// Default has default : {} -[[] + a:default:1]-> a | a implements Default +/// Default implements default : {} -[[] + a:default:1]-> a | a implements Default /// /// A := {} /// default = \{} -[[closA]]-> @A {} @@ -144,7 +144,7 @@ pub struct IAbilitiesStore { /// /// For example, in the program /// - /// Hash has hash : a -> U64 | a implements Hash + /// Hash implements hash : a -> U64 | a implements Hash /// /// Id := {} implements [Hash {hash: myHash}] /// myHash = \@Id n -> n @@ -155,7 +155,7 @@ pub struct IAbilitiesStore { /// Information about all members composing abilities. ability_members: MutMap>, - /// Maps a tuple (member, type) specifying that `type` has an implementation of an ability + /// Maps a tuple (member, type) specifying that `type` implements an ability /// member `member`, to how that implementation is defined. declared_implementations: MutMap, @@ -414,7 +414,7 @@ impl IAbilitiesStore { } /// Returns an iterator over pairs ((ability member, type), implementation) specifying that - /// the give type has an implementation of an ability member. + /// the give type implements an ability member. pub fn iter_declared_implementations( &self, ) -> impl Iterator + '_ { diff --git a/crates/compiler/can/src/annotation.rs b/crates/compiler/can/src/annotation.rs index 7906ccb5e62..61e53000c2e 100644 --- a/crates/compiler/can/src/annotation.rs +++ b/crates/compiler/can/src/annotation.rs @@ -122,7 +122,7 @@ pub struct NamedVariable { pub first_seen: Region, } -/// A type variable bound to an ability, like "a has Hash". +/// A type variable bound to an ability, like "a implements Hash". #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct AbleVariable { pub variable: Variable, @@ -1040,7 +1040,7 @@ fn can_annotation_help( Where(_annotation, clauses) => { debug_assert!(!clauses.is_empty()); - // Has clauses are allowed only on the top level of a signature, which we handle elsewhere. + // Implements clauses are allowed only on the top level of a signature, which we handle elsewhere. env.problem(roc_problem::can::Problem::IllegalImplementsClause { region: Region::across_all(clauses.iter().map(|clause| &clause.region)), }); diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 94719ade9e4..3bd138657f1 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -510,7 +510,7 @@ 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 implements Eq + // Eq implements eq : a, a -> U64 | a implements Eq // // A := U8 implements [Eq {eq}] // @@ -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 implements Eq, b implements Eq + // Eq implements eq : a, b -> Bool | a implements 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( diff --git a/crates/compiler/can/src/scope.rs b/crates/compiler/can/src/scope.rs index 9c2cf0aa757..678714999bd 100644 --- a/crates/compiler/can/src/scope.rs +++ b/crates/compiler/can/src/scope.rs @@ -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 implements Eq` gets a shadow symbol it can use for its + /// member `Eq implements 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. diff --git a/crates/compiler/can/src/traverse.rs b/crates/compiler/can/src/traverse.rs index c22096ea722..cbd0c43938d 100644 --- a/crates/compiler/can/src/traverse.rs +++ b/crates/compiler/can/src/traverse.rs @@ -674,7 +674,7 @@ pub enum FoundSymbol { Symbol(Symbol), } -/// Given an ability Foo has foo : ..., returns (T, foo1) if the symbol at the given region is a +/// Given an ability Foo implements foo : ..., returns (T, foo1) if the symbol at the given region is a /// symbol foo1 that specializes foo for T. Otherwise if the symbol is foo but the specialization /// is unknown, (Foo, foo) is returned. Otherwise [None] is returned. pub fn find_symbol_at( diff --git a/crates/compiler/types/src/subs.rs b/crates/compiler/types/src/subs.rs index f244faa0f54..20ef7655f46 100644 --- a/crates/compiler/types/src/subs.rs +++ b/crates/compiler/types/src/subs.rs @@ -2359,7 +2359,7 @@ pub enum Content { /// This can only happen when unified with a [Self::RigidAbleVar]. FlexAbleVar(Option>, SubsSlice), /// Like a [Self::RigidVar], but is also bound to 1+ abilities. - /// For example, "a has Hash". + /// For example, "a implements Hash". RigidAbleVar(SubsIndex, SubsSlice), /// name given to a recursion variable RecursionVar { From d2503bb9f255e5d5ae710a6dc586d454fe6a4840 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 22:59:29 -0400 Subject: [PATCH 34/55] has -> implements --- crates/compiler/fmt/src/def.rs | 2 +- crates/compiler/test_derive/src/decoding.rs | 10 ++++----- crates/compiler/test_derive/src/encoding.rs | 24 ++++++++++----------- crates/compiler/test_derive/src/hash.rs | 24 ++++++++++----------- crates/compiler/test_derive/src/util.rs | 2 +- crates/compiler/types/src/pretty_print.rs | 2 +- crates/compiler/types/src/types.rs | 2 +- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/crates/compiler/fmt/src/def.rs b/crates/compiler/fmt/src/def.rs index b2066f5ffe2..ab53f9addad 100644 --- a/crates/compiler/fmt/src/def.rs +++ b/crates/compiler/fmt/src/def.rs @@ -134,7 +134,7 @@ impl<'a> Formattable for TypeDef<'a> { buf.indent(indent); } - buf.push_str(" has"); + buf.push_str(" implements"); if !self.is_multiline() { debug_assert_eq!(members.len(), 1); diff --git a/crates/compiler/test_derive/src/decoding.rs b/crates/compiler/test_derive/src/decoding.rs index d77a3b396f0..b9c024ec660 100644 --- a/crates/compiler/test_derive/src/decoding.rs +++ b/crates/compiler/test_derive/src/decoding.rs @@ -87,7 +87,7 @@ fn derivable_record_ext_flex_var() { fn derivable_record_ext_flex_able_var() { check_derivable( Decoder, - v!({ a: v!(STR), }a has Symbol::DECODE_DECODER ), + v!({ a: v!(STR), }a implements Symbol::DECODE_DECODER ), DeriveKey::Decoder(FlatDecodableKey::Record(vec!["a".into()])), ); } @@ -124,8 +124,8 @@ fn record_2_fields() { derive_test(Decoder, v!({first: v!(STR), second: v!(STR),}), |golden| { assert_snapshot!(golden, @r###" # derived for { first : Str, second : Str } - # Decoder { first : val, second : val1 } fmt | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding + # Decoder { first : val, second : val1 } fmt | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_{first,second} = @@ -181,8 +181,8 @@ fn tuple_2_fields() { derive_test(Decoder, v!((v!(STR), v!(U8),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( Str, U8 )* - # Decoder ( val, val1 )* fmt | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt implements DecoderFormatting, val has Decoding, val1 implements Decoding + # Decoder ( val, val1 )* fmt | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_(arity:2) = diff --git a/crates/compiler/test_derive/src/encoding.rs b/crates/compiler/test_derive/src/encoding.rs index 1bf376ec25b..481ab8ff7a3 100644 --- a/crates/compiler/test_derive/src/encoding.rs +++ b/crates/compiler/test_derive/src/encoding.rs @@ -139,7 +139,7 @@ fn derivable_record_ext_flex_var() { fn derivable_record_ext_flex_able_var() { check_derivable( ToEncoder, - v!({ a: v!(STR), }a has Symbol::ENCODE_TO_ENCODER), + v!({ a: v!(STR), }a implements Symbol::ENCODE_TO_ENCODER), DeriveKey::ToEncoder(FlatEncodableKey::Record(vec!["a".into()])), ); } @@ -166,7 +166,7 @@ fn derivable_tag_ext_flex_var() { fn derivable_tag_ext_flex_able_var() { check_derivable( ToEncoder, - v!([ A v!(STR) ]a has Symbol::ENCODE_TO_ENCODER), + v!([ A v!(STR) ]a implements Symbol::ENCODE_TO_ENCODER), DeriveKey::ToEncoder(FlatEncodableKey::TagUnion(vec![("A".into(), 1)])), ); } @@ -251,8 +251,8 @@ fn two_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a,b}(0)]] # @<2>: [[custom(2) { a : val, b : val1 }]] | val implements Encoding, val1 implements Encoding @@ -278,8 +278,8 @@ fn two_field_tuple() { derive_test(ToEncoder, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding - # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_(arity:2)(0)]] # @<2>: [[custom(2) ( val, val1 )*]] | val implements Encoding, val1 implements Encoding @@ -338,8 +338,8 @@ fn tag_one_label_two_args() { derive_test(ToEncoder, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding - # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 2](0)]] # @<2>: [[custom(4) [A val val1]]] | val implements Encoding, val1 implements Encoding @@ -366,8 +366,8 @@ fn tag_two_labels() { |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 3,B 1](0)]] # @<2>: [[custom(6) [A val val1 val1, B val1]]] | val implements Encoding, val1 implements Encoding @@ -402,8 +402,8 @@ fn recursive_tag_union() { |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt implements EncoderFormatting, val has Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[Cons 2,Nil 0](0)]] # @<2>: [[custom(4) [Cons val val1, Nil]]] | val implements Encoding, val1 implements Encoding diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index a13fc7187bd..1d645d5d8a4 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -102,7 +102,7 @@ fn derivable_record_ext_flex_var() { fn derivable_record_ext_flex_able_var() { check_derivable( Hash, - v!({ a: v!(STR), }a has Symbol::DECODE_DECODER ), + v!({ a: v!(STR), }a implements Symbol::DECODE_DECODER ), DeriveKey::Hash(FlatHashKey::Record(vec!["a".into()])), ); } @@ -129,7 +129,7 @@ fn derivable_tag_ext_flex_var() { fn derivable_tag_ext_flex_able_var() { check_derivable( Hash, - v!([ A v!(STR) ]a has Symbol::ENCODE_TO_ENCODER), + v!([ A v!(STR) ]a implements Symbol::ENCODE_TO_ENCODER), DeriveKey::Hash(FlatHashKey::TagUnion(vec![("A".into(), 1)])), ); } @@ -197,8 +197,8 @@ fn two_field_record() { derive_test(Hash, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a,b}(0)]] #Derived.hash_{a,b} = @@ -214,8 +214,8 @@ fn two_element_tuple() { derive_test(Hash, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_(arity:2)(0)]] #Derived.hash_(arity:2) = @@ -246,8 +246,8 @@ fn tag_one_label_newtype() { derive_test(Hash, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 has Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 2](0)]] #Derived.hash_[A 2] = @@ -263,8 +263,8 @@ fn tag_two_labels() { derive_test(Hash, v!([A v!(U8) v!(STR) v!(U16), B v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 has Hash, a2 has Hash, a3 implements Hash - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 has Hash, a2 has Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash, a3 implements Hash # Specialization lambda sets: # @<1>: [[hash_[A 3,B 1](0)]] #Derived.hash_[A 3,B 1] = @@ -304,8 +304,8 @@ fn recursive_tag_union() { derive_test(Hash, v!([Nil, Cons v!(U8) v!(^lst) ] as lst), |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 has Hash, a2 implements Hash - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 has Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash # Specialization lambda sets: # @<1>: [[hash_[Cons 2,Nil 0](0)]] #Derived.hash_[Cons 2,Nil 0] = diff --git a/crates/compiler/test_derive/src/util.rs b/crates/compiler/test_derive/src/util.rs index 566d433c9c0..5e5edd4c446 100644 --- a/crates/compiler/test_derive/src/util.rs +++ b/crates/compiler/test_derive/src/util.rs @@ -182,7 +182,7 @@ macro_rules! v { use roc_types::subs::{Subs, Content}; |subs: &mut Subs| { roc_derive::synth_var(subs, Content::FlexVar(None)) } }}; - ($name:ident has $ability:path) => {{ + ($name:ident implements $ability:path) => {{ use roc_types::subs::{Subs, SubsIndex, SubsSlice, Content}; |subs: &mut Subs| { let name_index = diff --git a/crates/compiler/types/src/pretty_print.rs b/crates/compiler/types/src/pretty_print.rs index 8e6d41d0316..b5bf03f4a24 100644 --- a/crates/compiler/types/src/pretty_print.rs +++ b/crates/compiler/types/src/pretty_print.rs @@ -604,7 +604,7 @@ fn variable_to_string( for (i, (var, abilities)) in ctx.able_variables.into_iter().enumerate() { buf.push_str(if i == 0 { " | " } else { ", " }); buf.push_str(var); - buf.push_str(" has"); + buf.push_str(" implements"); for (i, ability) in abilities.into_sorted_iter().enumerate() { if i > 0 { buf.push_str(" &"); diff --git a/crates/compiler/types/src/types.rs b/crates/compiler/types/src/types.rs index 8d668e8207a..ded26f98193 100644 --- a/crates/compiler/types/src/types.rs +++ b/crates/compiler/types/src/types.rs @@ -4005,7 +4005,7 @@ fn write_debug_error_type_help(error_type: ErrorType, buf: &mut String, parens: buf.push('('); } buf.push_str(name.as_str()); - write!(buf, "has {:?}", symbol).unwrap(); + write!(buf, "implements {:?}", symbol).unwrap(); if write_parens { buf.push(')'); } From 76c54c2e7af08bf3cbc26e923f10bd67aa74eba9 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 23:09:22 -0400 Subject: [PATCH 35/55] `loc_has_parser` -> `loc_implements_parser` --- crates/compiler/parse/src/expr.rs | 4 ++-- crates/compiler/parse/src/pattern.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 2e787bdc344..9d93de6b31f 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -15,7 +15,7 @@ use crate::parser::{ word2, EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType, EWhen, Either, ParseResult, Parser, }; -use crate::pattern::{closure_param, loc_has_parser}; +use crate::pattern::{closure_param, loc_implements_parser}; use crate::state::State; use crate::string_literal::StrLikeLiteral; use crate::type_annotation; @@ -618,7 +618,7 @@ pub fn parse_single_def<'a>( if let Some((name, name_region, args)) = opt_tag_and_args { if let Ok((_, loc_has, state)) = - loc_has_parser().parse(arena, state.clone(), min_indent) + loc_implements_parser().parse(arena, state.clone(), min_indent) { let (_, (type_def, def_region), state) = finish_parsing_ability_def_help( min_indent, diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index 96c3b3c7201..e279f37c630 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -154,7 +154,7 @@ fn loc_tag_pattern_arg<'a>( } } -pub fn loc_has_parser<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { +pub fn loc_implements_parser<'a>() -> impl Parser<'a, Loc>, EPattern<'a>> { then( loc_tag_pattern_arg(false), |_arena, state, progress, pattern| { From edf969809e826741961fc3d9bb5851e1e0f030c8 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 23:14:30 -0400 Subject: [PATCH 36/55] `alias_in_has_clause` -> `alias_in_implements_clause` --- crates/reporting/tests/test_reporting.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index a983adc8bc4..7816cc8195e 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -8444,7 +8444,7 @@ In roc, functions are always written as a lambda, like{} ); test_report!( - alias_in_has_clause, + alias_in_implements_clause, indoc!( r#" app "test" provides [hash] to "./platform" From 76551375b9bbc6493c2035c99f774ef96dd666b5 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 26 May 2023 23:25:21 -0400 Subject: [PATCH 37/55] has -> implements in fn names --- crates/compiler/test_syntax/tests/test_fmt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/test_syntax/tests/test_fmt.rs b/crates/compiler/test_syntax/tests/test_fmt.rs index 8d092432bf5..4725aac92c2 100644 --- a/crates/compiler/test_syntax/tests/test_fmt.rs +++ b/crates/compiler/test_syntax/tests/test_fmt.rs @@ -5425,7 +5425,7 @@ mod test_fmt { } #[test] - fn opaque_has_clause() { + fn opaque_implements_clause() { expr_formats_same(indoc!( r#" A := U8 implements [Eq, Hash] @@ -5522,7 +5522,7 @@ mod test_fmt { } #[test] - fn opaque_has_with_impls() { + fn opaque_implements_with_impls() { expr_formats_same(indoc!( r#" A := U8 implements [Eq { eq }, Hash { hash }] From 9640fcb6d4d390bce313f9631001897de175e248 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sun, 28 May 2023 13:07:48 -0400 Subject: [PATCH 38/55] Fix reporting tests --- crates/reporting/tests/test_reporting.rs | 103 ++++++++++++----------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 7816cc8195e..6b3e7cd079c 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -8278,7 +8278,7 @@ In roc, functions are always written as a lambda, like{} ability_non_signature_expression, indoc!( r#" - MEq implememts + MEq implements 123 1 @@ -8453,12 +8453,12 @@ In roc, functions are always written as a lambda, like{} "# ), @r###" - ── IMPLEMENTS CLAUSE IS NOT AN ABILITY ──────────────────── /code/proj/Main.roc ─ + ── IMPLEMENTS CLAUSE IS NOT AN ABILITY ─────────────────── /code/proj/Main.roc ─ - The type referenced in this "implememts" clause is not an ability: + The type referenced in this "implements" clause is not an ability: - 3│ MHash has hash : a, b -> Num.U64 | a implements MHash, b implements Bool.Bool - ^^^^^^^^^ + 3│ MHash implements hash : a, b -> Num.U64 | a implements MHash, b implements Bool.Bool + ^^^^^^^^^ "### ); @@ -8530,14 +8530,14 @@ In roc, functions are always written as a lambda, like{} @r#" ── ABILITY MEMBER MISSING IMPLEMENTS CLAUSE ────────────── /code/proj/Main.roc ─ - The definition of the ability member `ab` does not include an `implements` clause - binding a type variable to the ability `Ability`: + The definition of the ability member `ab` does not include an `implements` + clause binding a type variable to the ability `Ability`: 3│ Ability implements ab : {} -> {} ^^ - Ability members must include an `implements` clause binding a type variable to - an ability, like + Ability members must include an `implements` clause binding a type + variable to an ability, like a implements Ability @@ -8600,18 +8600,19 @@ In roc, functions are always written as a lambda, like{} 3│ MHash implements hash : (a | a implements MHash) -> Num.U64 ^^^^^^^^^^^^^^^^^^ - `implements` clauses can only be specified on the top-level type annotations. + `implements` clauses can only be specified on the top-level type + annotations. ── ABILITY MEMBER MISSING IMPLEMENTS CLAUSE ────────────── /code/proj/Main.roc ─ - The definition of the ability member `hash` does not include an `implements` - clause binding a type variable to the ability `MHash`: + The definition of the ability member `hash` does not include an + `implements` clause binding a type variable to the ability `MHash`: 3│ MHash implements hash : (a | a implements MHash) -> Num.U64 ^^^^ - Ability members must include an `implements` clause binding a type variable to - an ability, like + Ability members must include an `implements` clause binding a type + variable to an ability, like a implements MHash @@ -8963,8 +8964,8 @@ In roc, functions are always written as a lambda, like{} a | a implements MHash - Note: The type variable `a` says it can take on any value that implements the - ability `MHash`. + Note: The type variable `a` says it can take on any value that + implements the ability `MHash`. But, I see that the type is only ever used as a a `Id` value. Can you replace `a` with a more specific type? @@ -9153,7 +9154,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [main] to "./platform" - Default has default : {} -> a | a implements Default + Default implements default : {} -> a | a implements Default main = A := {} implements [Default {default}] @@ -9361,7 +9362,7 @@ In roc, functions are always written as a lambda, like{} cannot be generated. Tip: `A` does not implement `Encoding`. Consider adding a custom - implementation or `has Encode.Encoding` to the definition of `A`. + implementation or `implements Encode.Encoding` to the definition of `A`. "### ); @@ -9404,7 +9405,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> U64 | a implements MEq + MEq implements eq : a, a -> U64 | a implements MEq A := U8 implements [MEq {eq}] "# @@ -9440,7 +9441,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A, myMEq] to "./platform" - MEq has eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool | a implements MEq A := U8 implements [ MEq {eq: aMEq} ] @@ -9481,7 +9482,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A, myMEq] to "./platform" - MEq has eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool | a implements MEq A := U8 implements [ MEq {eq ? aMEq} ] @@ -9537,8 +9538,8 @@ In roc, functions are always written as a lambda, like{} Custom implementations must be supplied fully. Hint: if you want this implementation to be derived, don't include a - record of implementations. For example, implements [Encoding] will attempt - to derive `Encoding` + record of implementations. For example, implements [Encoding] will + attempt to derive `Encoding` ── INCOMPLETE ABILITY IMPLEMENTATION ───────────────────── /code/proj/Main.roc ─ @@ -9559,7 +9560,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool | a implements MEq A := U8 implements [ MEq {eq : Bool.eq} ] "# @@ -9594,7 +9595,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool | a implements MEq A := U8 implements [ MEq {eq : \m, n -> m == n} ] "# @@ -9631,7 +9632,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq has eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool | a implements MEq A := U8 implements [ MEq {eq: eqA, eq: eqA} ] @@ -9684,7 +9685,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - Ab has ab : a -> a | a implements Ab + Ab implements ab : a -> a | a implements Ab A := {} implements [Ab] "# @@ -9746,7 +9747,7 @@ In roc, functions are always written as a lambda, like{} ^^^^^^^^^^^^^^^ Tip: `B` does not implement `Encoding`. Consider adding a custom - implementation or `has Encode.Encoding` to the definition of `B`. + implementation or `implements Encode.Encoding` to the definition of `B`. Tip: You can define a custom implementation of `Encoding` for `A`. "### @@ -9945,7 +9946,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [x] to "./platform" - Foo has foo : a -> a | a implements Foo + Foo implements foo : a -> a | a implements Foo F a b := b | a implements Foo @@ -10475,7 +10476,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [hash, Id] to "./platform" - MHash has hash : a -> U64 | a implements MHash + MHash implements hash : a -> U64 | a implements MHash Id := {} @@ -10618,9 +10619,10 @@ I recommend using camelCase. It's the standard style in Roc code! ^^^^^^^^^^^^^^^ Tip: `B` does not implement `Decoding`. Consider adding a custom - implementation or `has Decode.Decoding` to the definition of `B`. + implementation or `implements Decode.Decoding` to the definition of `B`. Tip: You can define a custom implementation of `Decoding` for `A`. + "### ); @@ -10713,7 +10715,7 @@ I recommend using camelCase. It's the standard style in Roc code! cannot be generated. Tip: `A` does not implement `Decoding`. Consider adding a custom - implementation or `has Decode.Decoding` to the definition of `A`. + implementation or `implements Decode.Decoding` to the definition of `A`. "### ); @@ -11282,9 +11284,10 @@ I recommend using camelCase. It's the standard style in Roc code! ^^^^ Tip: `B` does not implement `Hash`. Consider adding a custom - implementation or `has Hash.Hash` to the definition of `B`. + implementation or `implements Hash.Hash` to the definition of `B`. Tip: You can define a custom implementation of `Hash` for `A`. + "### ); @@ -11667,9 +11670,10 @@ I recommend using camelCase. It's the standard style in Roc code! ^^ Tip: `B` does not implement `Eq`. Consider adding a custom implementation - or `has Bool.Eq` to the definition of `B`. + or `implements Bool.Eq` to the definition of `B`. Tip: You can define a custom implementation of `Eq` for `A`. + "### ); @@ -12047,7 +12051,8 @@ I recommend using camelCase. It's the standard style in Roc code! 4│ f : a -> {} | a implements Hash & Hash ^^^^ - Abilities only need to bound to a type variable once in an `implements` clause! + Abilities only need to bound to a type variable once in an `implements` + clause! "### ); @@ -12079,12 +12084,12 @@ I recommend using camelCase. It's the standard style in Roc code! x | x implements Encoding & Decoding - Note: The type variable `x` says it can take on any value that has only - the ability `Encoding`. + Note: The type variable `x` says it can take on any value that + implements only the ability `Encoding`. - But, I see that it's also used as if it implements the ability `Decoding`. Can - you use `x` without that ability? If not, consider adding it to the `implements` - clause of `x`. + But, I see that it's also used as if it implements the ability + `Decoding`. Can you use `x` without that ability? If not, consider adding + it to the `implements` clause of `x`. "### ); @@ -12116,11 +12121,11 @@ I recommend using camelCase. It's the standard style in Roc code! x | x implements Hash & Encoding & Decoding - Note: The type variable `x` says it can take on any value that implements only - the ability `Encoding`. + Note: The type variable `x` says it can take on any value that + implements only the ability `Encoding`. - But, I see that it's also used as if it implements the abilities `Hash` and - `Decoding`. Can you use `x` without those abilities? If not, consider + But, I see that it's also used as if it implements the abilities `Hash` + and `Decoding`. Can you use `x` without those abilities? If not, consider adding them to the `implements` clause of `x`. "### ); @@ -12154,12 +12159,12 @@ I recommend using camelCase. It's the standard style in Roc code! x | x implements Encoding & Decoding - Note: The type variable `x` says it can take on any value that implements only - the abilities `Hash` and `Encoding`. + Note: The type variable `x` says it can take on any value that + implements only the abilities `Hash` and `Encoding`. - But, I see that it's also used as if it implements the ability `Decoding`. Can - you use `x` without that ability? If not, consider adding it to the `implements` - clause of `x`. + But, I see that it's also used as if it implements the ability + `Decoding`. Can you use `x` without that ability? If not, consider adding + it to the `implements` clause of `x`. "### ); From e514d0cb8398b413c111cb2003338f667506b764 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Mon, 29 May 2023 07:21:27 -0400 Subject: [PATCH 39/55] Define and use IMPLEMENTS const in roc_parse::keyword --- Cargo.lock | 1 + crates/compiler/fmt/src/annotation.rs | 4 ++-- crates/compiler/fmt/src/def.rs | 4 ++-- crates/compiler/parse/src/expr.rs | 2 +- crates/compiler/parse/src/keyword.rs | 5 +++++ crates/compiler/parse/src/pattern.rs | 7 +++++-- crates/compiler/parse/src/type_annotation.rs | 6 +++--- crates/compiler/types/Cargo.toml | 1 + crates/compiler/types/src/pretty_print.rs | 3 ++- crates/compiler/types/src/types.rs | 2 +- crates/reporting/src/error/canonicalize.rs | 18 +++++++++--------- crates/reporting/src/error/type.rs | 10 +++++----- 12 files changed, 37 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f93741602b9..05a7a9cc414 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4014,6 +4014,7 @@ dependencies = [ "roc_debug_flags", "roc_error_macros", "roc_module", + "roc_parse", "roc_region", "roc_serialize", "static_assertions", diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 02f5f58e101..472ff3ed9c9 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -654,7 +654,7 @@ impl<'a> Formattable for ImplementsClause<'a> { fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) { buf.push_str(self.var.value.extract_spaces().item); buf.spaces(1); - buf.push_str("implements"); + buf.push_str(roc_parse::keyword::IMPLEMENTS); buf.spaces(1); for (i, ab) in self.abilities.iter().enumerate() { @@ -753,7 +753,7 @@ impl<'a> Formattable for ImplementsAbilities<'a> { buf.newline(); buf.indent(indent); } - buf.push_str("implements"); + buf.push_str(roc_parse::keyword::IMPLEMENTS); buf.spaces(1); fmt_collection(buf, indent, Braces::Square, *has_abilities, Newlines::No); } diff --git a/crates/compiler/fmt/src/def.rs b/crates/compiler/fmt/src/def.rs index ab53f9addad..c71d327d9cd 100644 --- a/crates/compiler/fmt/src/def.rs +++ b/crates/compiler/fmt/src/def.rs @@ -133,8 +133,8 @@ impl<'a> Formattable for TypeDef<'a> { fmt_pattern(buf, &var.value, indent, Parens::NotNeeded); buf.indent(indent); } - - buf.push_str(" implements"); + buf.push(' '); + buf.push_str(roc_parse::keyword::IMPLEMENTS); if !self.is_multiline() { debug_assert_eq!(members.len(), 1); diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 9d93de6b31f..6b279cef38f 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1641,7 +1641,7 @@ fn parse_expr_end<'a>( value: Expr::Var { module_name: "", - ident: "implements", + ident: crate::keyword::IMPLEMENTS, }, .. }, diff --git a/crates/compiler/parse/src/keyword.rs b/crates/compiler/parse/src/keyword.rs index e20ce81870a..e37f0c5e5c9 100644 --- a/crates/compiler/parse/src/keyword.rs +++ b/crates/compiler/parse/src/keyword.rs @@ -1,3 +1,4 @@ +// These keywords are valid in expressions pub const IF: &str = "if"; pub const THEN: &str = "then"; pub const ELSE: &str = "else"; @@ -9,4 +10,8 @@ pub const EXPECT: &str = "expect"; pub const EXPECT_FX: &str = "expect-fx"; pub const CRASH: &str = "crash"; +// These keywords are valid in types +pub const IMPLEMENTS: &str = "implements"; +pub const WHERE: &str = "where"; + pub const KEYWORDS: [&str; 10] = [IF, THEN, ELSE, WHEN, AS, IS, DBG, EXPECT, EXPECT_FX, CRASH]; diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index e279f37c630..19afb719b90 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -138,7 +138,7 @@ fn loc_tag_pattern_arg<'a>( let Loc { region, value } = loc_pat; - if stop_on_has_kw && matches!(value, Pattern::Identifier("implements")) { + if stop_on_has_kw && matches!(value, Pattern::Identifier(crate::keyword::IMPLEMENTS)) { Err((NoProgress, EPattern::End(original_state.pos()))) } else { Ok(( @@ -158,7 +158,10 @@ pub fn loc_implements_parser<'a>() -> impl Parser<'a, Loc>, EPatt then( loc_tag_pattern_arg(false), |_arena, state, progress, pattern| { - if matches!(pattern.value, Pattern::Identifier("implements")) { + if matches!( + pattern.value, + Pattern::Identifier(crate::keyword::IMPLEMENTS) + ) { Ok(( progress, Loc::at(pattern.region, Implements::Implements), diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 2de4dbde4be..a0fab6842ff 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -459,7 +459,7 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<' ), skip_first!( // Parse "implements"; we don't care about this keyword - word("implements", EType::THasClause), + word(crate::keyword::IMPLEMENTS, EType::THasClause), // Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash" absolute_column_min_indent(ability_chain()) ) @@ -512,7 +512,7 @@ fn implements_clause_chain<'a>( pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { increment_min_indent(skip_first!( // Parse "implements"; we don't care about this keyword - word("implements", EType::THasClause), + word(crate::keyword::IMPLEMENTS, EType::THasClause), // Parse "Hash"; this may be qualified from another module like "Hash.Hash" space0_before_e( loc!(map!( @@ -726,7 +726,7 @@ fn parse_type_variable<'a>( min_indent, ) { Ok((_, name, state)) => { - if name == "implements" && stop_at_surface_has { + if name == crate::keyword::IMPLEMENTS && stop_at_surface_has { Err((NoProgress, EType::TEnd(state.pos()))) } else { let answer = TypeAnnotation::BoundVariable(name); diff --git a/crates/compiler/types/Cargo.toml b/crates/compiler/types/Cargo.toml index bb727200eaa..535490107e9 100644 --- a/crates/compiler/types/Cargo.toml +++ b/crates/compiler/types/Cargo.toml @@ -14,6 +14,7 @@ roc_error_macros = { path = "../../error_macros" } roc_module = { path = "../module" } roc_region = { path = "../region" } roc_serialize = { path = "../serialize" } +roc_parse = { path = "../parse" } ven_pretty = { path = "../../vendor/pretty" } diff --git a/crates/compiler/types/src/pretty_print.rs b/crates/compiler/types/src/pretty_print.rs index b5bf03f4a24..b132a0199e4 100644 --- a/crates/compiler/types/src/pretty_print.rs +++ b/crates/compiler/types/src/pretty_print.rs @@ -604,7 +604,8 @@ fn variable_to_string( for (i, (var, abilities)) in ctx.able_variables.into_iter().enumerate() { buf.push_str(if i == 0 { " | " } else { ", " }); buf.push_str(var); - buf.push_str(" implements"); + buf.push(' '); + buf.push_str(roc_parse::keyword::IMPLEMENTS); for (i, ability) in abilities.into_sorted_iter().enumerate() { if i > 0 { buf.push_str(" &"); diff --git a/crates/compiler/types/src/types.rs b/crates/compiler/types/src/types.rs index ded26f98193..efd49d2088f 100644 --- a/crates/compiler/types/src/types.rs +++ b/crates/compiler/types/src/types.rs @@ -4005,7 +4005,7 @@ fn write_debug_error_type_help(error_type: ErrorType, buf: &mut String, parens: buf.push('('); } buf.push_str(name.as_str()); - write!(buf, "implements {:?}", symbol).unwrap(); + write!(buf, "{} {:?}", roc_parse::keyword::IMPLEMENTS, symbol).unwrap(); if write_parens { buf.push(')'); } diff --git a/crates/reporting/src/error/canonicalize.rs b/crates/reporting/src/error/canonicalize.rs index a3332a06f29..47f770890e0 100644 --- a/crates/reporting/src/error/canonicalize.rs +++ b/crates/reporting/src/error/canonicalize.rs @@ -664,12 +664,12 @@ pub fn can_problem<'b>( doc = alloc.stack([ alloc.concat([ alloc.reflow("An "), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause is not allowed here:"), ]), alloc.region(lines.convert_region(region)), alloc.concat([ - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow( " clauses can only be specified on the top-level type annotations.", ), @@ -688,7 +688,7 @@ pub fn can_problem<'b>( alloc.region(lines.convert_region(region)), alloc.concat([ alloc.reflow("Abilities only need to bound to a type variable once in an "), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause!"), ]), ]); @@ -705,7 +705,7 @@ pub fn can_problem<'b>( alloc.reflow("The definition of the ability member "), alloc.symbol_unqualified(member), alloc.reflow(" does not include an "), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause binding a type variable to the ability "), alloc.symbol_unqualified(ability), alloc.reflow(":"), @@ -713,13 +713,13 @@ pub fn can_problem<'b>( alloc.region(lines.convert_region(region)), alloc.concat([ alloc.reflow("Ability members must include an "), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause binding a type variable to an ability, like"), ]), alloc.type_block(alloc.concat([ alloc.type_variable("a".into()), alloc.space(), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.space(), alloc.symbol_unqualified(ability), ])), @@ -781,12 +781,12 @@ pub fn can_problem<'b>( alloc .hint("") .append(alloc.reflow("Perhaps you meant to include an ")) - .append(alloc.keyword("implements")) + .append(alloc.keyword(roc_parse::keyword::IMPLEMENTS)) .append(alloc.reflow(" annotation, like")), alloc.type_block(alloc.concat([ alloc.type_variable(suggested_var_name), alloc.space(), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.space(), alloc.symbol_unqualified(ability), ])), @@ -853,7 +853,7 @@ pub fn can_problem<'b>( let hint = if ability.is_builtin() { alloc.hint("").append( alloc.reflow("if you want this implementation to be derived, don't include a record of implementations. For example,") - .append(alloc.type_block(alloc.concat([alloc.type_str("implements ["), alloc.symbol_unqualified(ability), alloc.type_str("]")]))) + .append(alloc.type_block(alloc.concat([alloc.type_str(roc_parse::keyword::IMPLEMENTS), alloc.type_str(" ["), alloc.symbol_unqualified(ability), alloc.type_str("]")]))) .append(alloc.reflow(" will attempt to derive ").append(alloc.symbol_unqualified(ability)))) } else { alloc.nil() diff --git a/crates/reporting/src/error/type.rs b/crates/reporting/src/error/type.rs index 9647b0208b7..2223bbd825d 100644 --- a/crates/reporting/src/error/type.rs +++ b/crates/reporting/src/error/type.rs @@ -373,7 +373,7 @@ fn underivable_hint<'b>( alloc.concat([ alloc.reflow(" or "), alloc.inline_type_block(alloc.concat([ - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.space(), alloc.symbol_qualified(ability), ])), @@ -400,13 +400,13 @@ fn underivable_hint<'b>( alloc.reflow("This type variable is not bound to "), alloc.symbol_unqualified(ability), alloc.reflow(". Consider adding an "), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause to bind the type variable, like "), alloc.inline_type_block(alloc.concat([ alloc.string("| ".to_string()), alloc.type_variable(v.clone()), alloc.space(), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.space(), alloc.symbol_qualified(ability), ])), @@ -2758,7 +2758,7 @@ fn type_with_able_vars<'b>( doc.push(alloc.string(if i == 0 { " | " } else { ", " }.to_string())); doc.push(alloc.type_variable(var)); doc.push(alloc.space()); - doc.push(alloc.keyword("implements")); + doc.push(alloc.keyword(roc_parse::keyword::IMPLEMENTS)); for (i, ability) in abilities.into_sorted_iter().enumerate() { if i > 0 { @@ -4532,7 +4532,7 @@ fn type_problem_to_pretty<'b>( alloc.reflow("it") }, alloc.reflow(" to the "), - alloc.keyword("implements"), + alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause of "), alloc.type_variable(name), alloc.reflow("."), From 9e4b14d3d9c79c78a4fc34428f27793745771c21 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Mon, 29 May 2023 07:22:50 -0400 Subject: [PATCH 40/55] Fix typo --- crates/compiler/can/src/abilities.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/can/src/abilities.rs b/crates/compiler/can/src/abilities.rs index 7f77c01bbaa..26d5643c9a5 100644 --- a/crates/compiler/can/src/abilities.rs +++ b/crates/compiler/can/src/abilities.rs @@ -414,7 +414,7 @@ impl IAbilitiesStore { } /// Returns an iterator over pairs ((ability member, type), implementation) specifying that - /// the give type implements an ability member. + /// the given type implements an ability member. pub fn iter_declared_implementations( &self, ) -> impl Iterator + '_ { From 98338f6e2052e8587f91becf689873638d100786 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Mon, 29 May 2023 08:35:51 -0400 Subject: [PATCH 41/55] has -> implements --- crates/compiler/builtins/roc/Hash.roc | 2 +- crates/compiler/builtins/roc/Set.roc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index 25aafdf5525..3bbff810d58 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -117,7 +117,7 @@ hashNat = \hasher, n -> i128OfDec : Dec -> I128 ## Adds a single [Dec] to a hasher. -hashDec : a, Dec -> a | a has Hasher +hashDec : a, Dec -> a | a implements Hasher hashDec = \hasher, n -> hashI128 hasher (i128OfDec n) ## Adds a container of [Hash]able elements to a [Hasher] by hashing each element. diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index fdbc1f41eda..660243881e4 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -47,7 +47,7 @@ isEq = \xs, ys -> else Break Bool.false -hashSet : hasher, Set k -> hasher | k has Hash & Eq, hasher has Hasher +hashSet : hasher, Set k -> hasher | k implements Hash & Eq, hasher implements Hasher hashSet = \hasher, @Set inner -> Hash.hash hasher inner ## Creates a new empty `Set`. From 35a27daecf5ffd43e6f775b869a40f7f2a9ac554 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Tue, 30 May 2023 07:32:29 -0400 Subject: [PATCH 42/55] formatting --- crates/compiler/builtins/roc/Set.roc | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index 660243881e4..4d08af15bfc 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -23,7 +23,6 @@ interface Set Hash.{ Hash, Hasher }, ] - ## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) ## type which stores a collection of unique values, without any ordering Set k := Dict.Dict k {} | k implements Hash & Eq From b4aa4a9089b71ed577ef82e3c2831a23cefc5a9e Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 2 Jun 2023 07:53:38 -0400 Subject: [PATCH 43/55] Fix syntax derp --- crates/compiler/builtins/roc/Dict.roc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index e02a2e52634..c5cb986aa4c 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -177,7 +177,7 @@ single = \k, v -> ## |> Dict.insert 4 "Four" ## |> Bool.isEq (Dict.fromList [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]) ## ``` -fromList : List (k, v) -> Dict k v | k Hash & Eq +fromList : List (k, v) -> Dict k v | k implements Hash & Eq fromList = \data -> # TODO: make this efficient. Should just set data and then set all indicies in the hashmap. List.walk data (empty {}) (\dict, (k, v) -> insert dict k v) @@ -687,7 +687,7 @@ rehash = \@Dict { metadata, dataIndices, data, size } -> rehashHelper newDict metadata dataIndices data 0 -rehashHelper : Dict k v, List I8, List Nat, List (k, v), Nat -> Dict k v | k implements Hash & implements +rehashHelper : Dict k v, List I8, List Nat, List (k, v), Nat -> Dict k v | k implements Hash & Eq rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> when List.get oldMetadata index is Ok md -> From fd846b9a7a05ecaa3d70efd24e52b03bccc18585 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Fri, 2 Jun 2023 07:53:52 -0400 Subject: [PATCH 44/55] increase stack size for debug tests --- crates/compiler/test_gen/src/gen_list.rs | 51 ++++++++++++++---------- crates/compiler/test_gen/src/gen_tags.rs | 19 +++++---- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index f343ea78308..2e0d767237b 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -3811,6 +3811,9 @@ fn list_range_length_overflow() { #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] mod pattern_match { + #[allow(unused_imports)] + use crate::helpers::with_larger_debug_stack; + #[cfg(feature = "gen-llvm")] use crate::helpers::llvm::assert_evals_to; @@ -3857,8 +3860,9 @@ mod pattern_match { #[test] fn ranged_matches_head() { - assert_evals_to!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + r#" helper = \l -> when l is [] -> 1u8 [A] -> 2u8 @@ -3874,21 +3878,23 @@ mod pattern_match { helper [B], helper [B, A], helper [B, B], helper [B, A, B, B], ] "#, - RocList::from_slice(&[ - 1, // - 2, // - 3, 3, 3, 3, // - 4, 4, 4, 4, // - 5, 5, 5, 5, // - ]), - RocList - ) + RocList::from_slice(&[ + 1, // + 2, // + 3, 3, 3, 3, // + 4, 4, 4, 4, // + 5, 5, 5, 5, // + ]), + RocList + ) + }) } #[test] fn ranged_matches_tail() { - assert_evals_to!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + r#" helper = \l -> when l is [] -> 1u8 [A] -> 2u8 @@ -3904,15 +3910,16 @@ mod pattern_match { helper [B], helper [A, B], helper [B, B], helper [B, A, B, B], ] "#, - RocList::from_slice(&[ - 1, // - 2, // - 3, 3, 3, 3, // - 4, 4, 4, 4, // - 5, 5, 5, 5, // - ]), - RocList - ) + RocList::from_slice(&[ + 1, // + 2, // + 3, 3, 3, 3, // + 4, 4, 4, 4, // + 5, 5, 5, 5, // + ]), + RocList + ) + }) } #[test] diff --git a/crates/compiler/test_gen/src/gen_tags.rs b/crates/compiler/test_gen/src/gen_tags.rs index bdfef4a93b6..970295ca24b 100644 --- a/crates/compiler/test_gen/src/gen_tags.rs +++ b/crates/compiler/test_gen/src/gen_tags.rs @@ -1,3 +1,6 @@ +#[allow(unused_imports)] +use crate::helpers::with_larger_debug_stack; + #[cfg(feature = "gen-llvm")] use crate::helpers::llvm::assert_evals_to; @@ -2167,9 +2170,10 @@ fn refcount_nullable_unwrapped_needing_no_refcount_issue_5027() { #[test] #[cfg(any(feature = "gen-llvm"))] fn issue_5162_recast_nested_nullable_unwrapped_layout() { - assert_evals_to!( - indoc!( - r###" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r###" app "test" provides [main] to "./platform" Concept : [ @@ -2184,10 +2188,11 @@ fn issue_5162_recast_nested_nullable_unwrapped_layout() { when Dict.single bottom 0 is _ -> Bool.true "### - ), - true, - bool - ); + ), + true, + bool + ); + }) } #[test] From cb08225bf0b85b6d6d46c9222d959bdfcbf45fa3 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Mon, 5 Jun 2023 20:19:00 -0400 Subject: [PATCH 45/55] `|` -> `where` --- .../cli_testing_examples/benchmarks/AStar.roc | 12 +- crates/compiler/builtins/roc/Bool.roc | 4 +- crates/compiler/builtins/roc/Decode.roc | 48 ++--- crates/compiler/builtins/roc/Dict.roc | 58 +++--- crates/compiler/builtins/roc/Encode.roc | 50 ++--- crates/compiler/builtins/roc/Hash.roc | 32 +-- crates/compiler/builtins/roc/List.roc | 10 +- crates/compiler/builtins/roc/Set.roc | 32 +-- crates/compiler/can/src/abilities.rs | 8 +- crates/compiler/can/src/def.rs | 4 +- crates/compiler/can/src/pattern.rs | 2 +- crates/compiler/can/src/scope.rs | 2 +- crates/compiler/derive/src/decoding.rs | 8 +- crates/compiler/derive/src/decoding/list.rs | 10 +- crates/compiler/derive/src/decoding/record.rs | 2 +- crates/compiler/derive/src/decoding/tuple.rs | 2 +- crates/compiler/derive/src/encoding.rs | 66 +++--- crates/compiler/derive/src/hash.rs | 14 +- crates/compiler/derive/src/util.rs | 2 +- crates/compiler/fmt/src/annotation.rs | 15 +- crates/compiler/fmt/src/def.rs | 2 +- crates/compiler/load_internal/src/file.rs | 2 +- .../build/interface_with_deps/AStar.roc | 12 +- .../compiler/load_internal/tests/test_load.rs | 12 +- crates/compiler/parse/src/ast.rs | 6 +- crates/compiler/parse/src/keyword.rs | 4 +- crates/compiler/parse/src/type_annotation.rs | 23 +- crates/compiler/solve/src/ability.rs | 2 +- crates/compiler/solve/src/solve.rs | 2 +- crates/compiler/solve/tests/solve_expr.rs | 20 +- crates/compiler/test_derive/src/decoding.rs | 12 +- crates/compiler/test_derive/src/encoding.rs | 54 ++--- crates/compiler/test_derive/src/hash.rs | 40 ++-- crates/compiler/test_gen/src/gen_abilities.rs | 46 ++-- crates/compiler/test_gen/src/gen_list.rs | 4 +- crates/compiler/test_gen/src/gen_num.rs | 2 +- crates/compiler/test_mono/src/tests.rs | 18 +- .../ability_demand_value_has_args.expr.roc | 2 +- ...y_demands_not_indented_with_first.expr.roc | 4 +- ..._first_demand_not_indented_enough.expr.roc | 2 +- .../pass/ability_single_line.expr.roc | 2 +- .../pass/ability_two_in_a_row.expr.roc | 4 +- .../opaque_has_abilities.expr.formatted.roc | 6 +- .../pass/opaque_has_abilities.expr.roc | 6 +- .../pass/where_clause_function.expr.roc | 2 +- ...ultiple_bound_abilities.expr.formatted.roc | 4 +- ...e_clause_multiple_bound_abilities.expr.roc | 4 +- .../pass/where_clause_multiple_has.expr.roc | 2 +- ...ple_has_across_newlines.expr.formatted.roc | 2 +- ...ause_multiple_has_across_newlines.expr.roc | 2 +- .../pass/where_clause_non_function.expr.roc | 2 +- ...where_clause_on_newline.expr.formatted.roc | 2 +- .../pass/where_clause_on_newline.expr.roc | 2 +- crates/compiler/test_syntax/tests/test_fmt.rs | 20 +- crates/compiler/types/src/pretty_print.rs | 8 +- crates/compiler/types/src/types.rs | 2 +- .../expand_able_variables_in_type_alias.txt | 4 +- ...bles_bound_to_an_ability_from_type_def.txt | 4 +- ...s_are_superset_of_flex_bounds_admitted.txt | 8 +- ...e_variable_bound_to_ability_issue_4408.txt | 4 +- .../uitest/tests/ability/smoke/decoder.txt | 12 +- .../uitest/tests/ability/smoke/encoder.txt | 12 +- .../tests/ability/specialize/bool_decoder.txt | 2 +- .../tests/ability/specialize/bool_hash.txt | 2 +- .../ability/specialize/bool_to_encoder.txt | 2 +- .../specialize/opaque_decoder_derive.txt | 2 +- .../specialize/opaque_encoder_derive.txt | 2 +- .../ability/specialize/opaque_hash_custom.txt | 2 +- .../ability/specialize/opaque_hash_derive.txt | 2 +- .../polymorphic_lambda_set_specialization.txt | 6 +- ...lambda_set_specialization_bound_output.txt | 6 +- ...ization_branching_over_single_variable.txt | 8 +- ...zation_varying_over_multiple_variables.txt | 20 +- ...ng_over_multiple_variables_two_results.txt | 24 +-- ...n_with_deep_specialization_and_capture.txt | 6 +- ...a_set_specialization_with_let_weakened.txt | 6 +- ...ialization_with_let_weakened_unapplied.txt | 12 +- .../ability/specialize/ranged_num_hash.txt | 2 +- .../ability/specialize/record_to_encoder.txt | 2 +- ...ord_to_encoder_with_nested_custom_impl.txt | 2 +- .../resolve_lambda_set_ability_chain.txt | 4 +- ...da_set_branches_ability_vs_non_ability.txt | 2 +- ...solve_lambda_set_branches_same_ability.txt | 2 +- ...e_lambda_set_generalized_ability_alias.txt | 6 +- ...olve_lambda_set_weakened_ability_alias.txt | 2 +- ...mutually_recursive_ability_lambda_sets.txt | 4 +- ...recursive_ability_lambda_sets_inferred.txt | 4 +- .../resolve_recursive_ability_lambda_set.txt | 2 +- ...cialized_lambda_sets_in_one_lambda_set.txt | 2 +- ..._unspecialized_lambda_set_behind_alias.txt | 4 +- ...unspecialized_lambda_set_behind_opaque.txt | 2 +- .../specialize/static_specialization.txt | 2 +- .../call_generic_ability_member.txt | 6 +- ...ed_specialization_with_annotation_only.txt | 2 +- ...checked_specialization_with_typed_body.txt | 2 +- ...bility_constrained_in_non_member_check.txt | 6 +- ...bility_constrained_in_non_member_infer.txt | 4 +- ..._constrained_in_non_member_infer_usage.txt | 2 +- ...in_non_member_multiple_specializations.txt | 2 +- .../solve/ability_specialization_called.txt | 2 +- .../tests/solve/alias_ability_member.txt | 4 +- .../tests/solve/alias_propagates_able_var.txt | 6 +- .../tests/solve/exposed_ability_name.txt | 4 +- ...ities_multiple_members_specializations.txt | 8 +- ...ility_multiple_members_specializations.txt | 4 +- ..._ability_single_member_specializations.txt | 2 +- crates/reporting/src/error/type.rs | 11 +- crates/reporting/tests/test_reporting.rs | 196 +++++++++--------- examples/cli/cli-platform/Env.roc | 4 +- examples/cli/cli-platform/File.roc | 4 +- examples/cli/cli-platform/Http.roc | 2 +- examples/python-interop/platform/main.roc | 2 +- examples/ruby-interop/platform/main.roc | 2 +- .../platform/Html/Internal/Client.roc | 6 +- .../platform/Html/Internal/Server.roc | 4 +- .../virtual-dom-wip/platform/client-side.roc | 2 +- www/generate_tutorial/src/tutorial.roc | 54 ++--- 117 files changed, 637 insertions(+), 612 deletions(-) diff --git a/crates/cli_testing_examples/benchmarks/AStar.roc b/crates/cli_testing_examples/benchmarks/AStar.roc index 95edcc7bc4a..14f4a42dbcf 100644 --- a/crates/cli_testing_examples/benchmarks/AStar.roc +++ b/crates/cli_testing_examples/benchmarks/AStar.roc @@ -10,9 +10,9 @@ Model position : { openSet : Set position, costs : Dict position F64, cameFrom : Dict position position, -} | position implements Hash & Eq +} where position implements Hash & Eq -initialModel : position -> Model position | position implements Hash & Eq +initialModel : position -> Model position where 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 implements Hash & Eq +cheapestOpen : (position -> F64), Model position -> Result position {} where 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 implements Hash & Eq +reconstructPath : Dict position position, position -> List position where 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 implements Hash & Eq +updateCost : position, position, Model position -> Model position where 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 implements Hash & Eq +astar : (position, position -> F64), (position -> Set position), position, Model position -> Result (List position) {} where position implements Hash & Eq astar = \costFn, moveFn, goal, model -> when cheapestOpen (\source -> costFn source goal) model is Err {} -> Err {} diff --git a/crates/compiler/builtins/roc/Bool.roc b/crates/compiler/builtins/roc/Bool.roc index 37eea3dff22..c6d331a915e 100644 --- a/crates/compiler/builtins/roc/Bool.roc +++ b/crates/compiler/builtins/roc/Bool.roc @@ -30,7 +30,7 @@ Eq implements ## for more detail. ## 5. Functions cannot be compared for structural equality, therefore Roc ## cannot derive `isEq` for types that contain functions. - isEq : a, a -> Bool | a implements Eq + isEq : a, a -> Bool where a implements Eq ## Represents the boolean true and false using an opaque type. ## `Bool` implements the `Eq` ability. @@ -116,7 +116,7 @@ not : Bool -> Bool ## expect (Bool.false != Bool.false) == Bool.false ## expect "Apples" != "Oranges" ## ``` -isNotEq : a, a -> Bool | a implements Eq +isNotEq : a, a -> Bool where a implements Eq isNotEq = \a, b -> structuralNotEq a b # INTERNAL COMPILER USE ONLY: used to lower calls to `isEq` to structural diff --git a/crates/compiler/builtins/roc/Decode.roc b/crates/compiler/builtins/roc/Decode.roc index 96b17ac237a..dc68427b811 100644 --- a/crates/compiler/builtins/roc/Decode.roc +++ b/crates/compiler/builtins/roc/Decode.roc @@ -73,30 +73,30 @@ DecodeResult val : { result : Result val DecodeError, rest : List U8 } ## Decodes a `List U8` of utf-8 bytes where `val` is the type of the decoded ## value, and `fmt` is a [Decoder] which implements the [DecoderFormatting] ## ability -Decoder val fmt := List U8, fmt -> DecodeResult val | fmt implements DecoderFormatting +Decoder val fmt := List U8, fmt -> DecodeResult val where fmt implements DecoderFormatting ## Definition of the [Decoding] ability Decoding implements - decoder : Decoder val fmt | val implements Decoding, fmt implements DecoderFormatting + decoder : Decoder val fmt where val implements Decoding, fmt implements DecoderFormatting ## Definition of the [DecoderFormatting] ability DecoderFormatting implements - u8 : Decoder U8 fmt | fmt implements DecoderFormatting - u16 : Decoder U16 fmt | fmt implements DecoderFormatting - u32 : Decoder U32 fmt | fmt implements DecoderFormatting - u64 : Decoder U64 fmt | fmt implements DecoderFormatting - u128 : Decoder U128 fmt | fmt implements DecoderFormatting - i8 : Decoder I8 fmt | fmt implements DecoderFormatting - i16 : Decoder I16 fmt | fmt implements DecoderFormatting - i32 : Decoder I32 fmt | fmt implements DecoderFormatting - i64 : Decoder I64 fmt | fmt implements DecoderFormatting - i128 : Decoder I128 fmt | fmt implements DecoderFormatting - f32 : Decoder F32 fmt | fmt implements DecoderFormatting - f64 : Decoder F64 fmt | fmt implements DecoderFormatting - dec : Decoder Dec fmt | fmt implements DecoderFormatting - bool : Decoder Bool fmt | fmt implements DecoderFormatting - string : Decoder Str fmt | fmt implements DecoderFormatting - list : Decoder elem fmt -> Decoder (List elem) fmt | fmt implements DecoderFormatting + u8 : Decoder U8 fmt where fmt implements DecoderFormatting + u16 : Decoder U16 fmt where fmt implements DecoderFormatting + u32 : Decoder U32 fmt where fmt implements DecoderFormatting + u64 : Decoder U64 fmt where fmt implements DecoderFormatting + u128 : Decoder U128 fmt where fmt implements DecoderFormatting + i8 : Decoder I8 fmt where fmt implements DecoderFormatting + i16 : Decoder I16 fmt where fmt implements DecoderFormatting + i32 : Decoder I32 fmt where fmt implements DecoderFormatting + i64 : Decoder I64 fmt where fmt implements DecoderFormatting + i128 : Decoder I128 fmt where fmt implements DecoderFormatting + f32 : Decoder F32 fmt where fmt implements DecoderFormatting + f64 : Decoder F64 fmt where fmt implements DecoderFormatting + dec : Decoder Dec fmt where fmt implements DecoderFormatting + bool : Decoder Bool fmt where fmt implements DecoderFormatting + string : Decoder Str fmt where fmt implements DecoderFormatting + list : Decoder elem fmt -> Decoder (List elem) fmt where fmt implements DecoderFormatting ## `record state stepField finalizer` decodes a record field-by-field. ## @@ -104,7 +104,7 @@ DecoderFormatting implements ## `Skip` if the field is not a part of the decoded record. ## ## `finalizer` should produce the record value from the decoded `state`. - record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt implements DecoderFormatting + record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt where fmt implements DecoderFormatting ## `tuple state stepElem finalizer` decodes a tuple element-by-element. ## @@ -113,7 +113,7 @@ DecoderFormatting implements ## index passed to `stepElem` is 0-indexed. ## ## `finalizer` should produce the tuple value from the decoded `state`. - tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt | fmt implements DecoderFormatting + tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt where fmt implements DecoderFormatting ## Build a custom [Decoder] function. For example the implementation of ## `decodeBool` could be defined as follows; @@ -125,11 +125,11 @@ DecoderFormatting implements ## ['t', 'r', 'u', 'e', ..] -> { result: Ok Bool.true, rest: List.drop bytes 4 } ## _ -> { result: Err TooShort, rest: bytes } ## ``` -custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt implements DecoderFormatting +custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt where fmt implements DecoderFormatting custom = \decode -> @Decoder decode ## Decode a `List U8` utf-8 bytes using a specific [Decoder] function -decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt implements DecoderFormatting +decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val where fmt implements DecoderFormatting decodeWith = \bytes, @Decoder decode, fmt -> decode bytes fmt ## Decode a `List U8` utf-8 bytes and return a [DecodeResult](#DecodeResult) @@ -141,7 +141,7 @@ decodeWith = \bytes, @Decoder decode, fmt -> decode bytes fmt ## ## actual.result == expected ## ``` -fromBytesPartial : List U8, fmt -> DecodeResult val | val implements Decoding, fmt implements DecoderFormatting +fromBytesPartial : List U8, fmt -> DecodeResult val where val implements Decoding, fmt implements DecoderFormatting fromBytesPartial = \bytes, fmt -> decodeWith bytes decoder fmt ## Decode a `List U8` utf-8 bytes and return a [Result] with no leftover bytes @@ -155,7 +155,7 @@ fromBytesPartial = \bytes, fmt -> decodeWith bytes decoder fmt ## ## actual == expected ## ``` -fromBytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError | val implements Decoding, fmt implements DecoderFormatting +fromBytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError where val implements Decoding, fmt implements DecoderFormatting fromBytes = \bytes, fmt -> when fromBytesPartial bytes fmt is { result, rest } -> diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index c5cb986aa4c..0e885571230 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -97,7 +97,7 @@ Dict k v := { dataIndices : List Nat, data : List (k, v), size : Nat, -} | k implements Hash & Eq +} where k implements Hash & Eq implements [ Eq { isEq, @@ -107,7 +107,7 @@ Dict k v := { }, ] -isEq : Dict k v, Dict k v -> Bool | k implements Hash & Eq, v implements Eq +isEq : Dict k v, Dict k v -> Bool where k implements Hash & Eq, v implements Eq isEq = \xs, ys -> if len xs != len ys then Bool.false @@ -120,14 +120,14 @@ isEq = \xs, ys -> _ -> Break Bool.false -hashDict : hasher, Dict k v -> hasher | k implements Hash & Eq, v implements Hash, hasher implements Hasher +hashDict : hasher, Dict k v -> hasher where k implements Hash & Eq, v implements Hash, hasher implements Hasher hashDict = \hasher, dict -> Hash.hashUnordered hasher (toList dict) List.walk ## Return an empty dictionary. ## ``` ## emptyDict = Dict.empty {} ## ``` -empty : {} -> Dict k v | k implements Hash & Eq +empty : {} -> Dict k v where k implements Hash & Eq empty = \{} -> @Dict { metadata: List.repeat emptySlot 8, @@ -144,7 +144,7 @@ empty = \{} -> ## ## capacityOfDict = Dict.capacity foodDict ## ``` -capacity : Dict k v -> Nat | k implements Hash & Eq +capacity : Dict k v -> Nat where k implements Hash & Eq capacity = \@Dict { dataIndices } -> cap = List.len dataIndices @@ -153,7 +153,7 @@ capacity = \@Dict { dataIndices } -> ## Return a dictionary with space allocated for a number of entries. This ## may provide a performance optimization if you know how many entries will be ## inserted. -withCapacity : Nat -> Dict k v | k implements Hash & Eq +withCapacity : Nat -> Dict k v where k implements Hash & Eq withCapacity = \_ -> # TODO: power of 2 * 8 and actual implementation empty {} @@ -164,7 +164,7 @@ withCapacity = \_ -> ## Dict.single "A" "B" ## |> Bool.isEq (Dict.insert (Dict.empty {}) "A" "B") ## ``` -single : k, v -> Dict k v | k implements Hash & Eq +single : k, v -> Dict k v where k implements Hash & Eq single = \k, v -> insert (empty {}) k v @@ -177,7 +177,7 @@ single = \k, v -> ## |> Dict.insert 4 "Four" ## |> Bool.isEq (Dict.fromList [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]) ## ``` -fromList : List (k, v) -> Dict k v | k implements Hash & Eq +fromList : List (k, v) -> Dict k v where k implements Hash & Eq fromList = \data -> # TODO: make this efficient. Should just set data and then set all indicies in the hashmap. List.walk data (empty {}) (\dict, (k, v) -> insert dict k v) @@ -192,7 +192,7 @@ fromList = \data -> ## |> Dict.len ## |> Bool.isEq 3 ## ``` -len : Dict k v -> Nat | k implements Hash & Eq +len : Dict k v -> Nat where k implements Hash & Eq len = \@Dict { size } -> size @@ -208,7 +208,7 @@ len = \@Dict { size } -> ## ## expect Dict.len clearSongs == 0 ## ``` -clear : Dict k v -> Dict k v | k implements Hash & Eq +clear : Dict k v -> Dict k v where k implements Hash & Eq clear = \@Dict { metadata, dataIndices, data } -> cap = List.len dataIndices @@ -236,7 +236,7 @@ clear = \@Dict { metadata, dataIndices, data } -> ## |> Dict.walk 0 (\count, _, qty -> count + qty) ## |> Bool.isEq 36 ## ``` -walk : Dict k v, state, (state, k, v -> state) -> state | k implements Hash & Eq +walk : Dict k v, state, (state, k, v -> state) -> state where k implements Hash & Eq walk = \@Dict { data }, initialState, transform -> List.walk data initialState (\state, (k, v) -> transform state k v) @@ -268,7 +268,7 @@ walk = \@Dict { data }, initialState, transform -> ## ## expect someoneIsAnAdult == Bool.true ## ``` -walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k implements Hash & Eq +walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state where k implements Hash & Eq walkUntil = \@Dict { data }, initialState, transform -> List.walkUntil data initialState (\state, (k, v) -> transform state k v) @@ -283,7 +283,7 @@ walkUntil = \@Dict { data }, initialState, transform -> ## expect Dict.get dictionary 1 == Ok "Apple" ## expect Dict.get dictionary 2000 == Err KeyNotFound ## ``` -get : Dict k v, k -> Result v [KeyNotFound] | k implements Hash & Eq +get : Dict k v, k -> Result v [KeyNotFound] where k implements Hash & Eq get = \@Dict { metadata, dataIndices, data }, key -> hashKey = createLowLevelHasher PseudoRandSeed @@ -311,7 +311,7 @@ get = \@Dict { metadata, dataIndices, data }, key -> ## |> Dict.contains 1234 ## |> Bool.isEq Bool.true ## ``` -contains : Dict k v, k -> Bool | k implements Hash & Eq +contains : Dict k v, k -> Bool where k implements Hash & Eq contains = \@Dict { metadata, dataIndices, data }, key -> hashKey = createLowLevelHasher PseudoRandSeed @@ -336,7 +336,7 @@ contains = \@Dict { metadata, dataIndices, data }, key -> ## |> Dict.get "Apples" ## |> Bool.isEq (Ok 12) ## ``` -insert : Dict k v, k, v -> Dict k v | k implements Hash & Eq +insert : Dict k v, k, v -> Dict k v where k implements Hash & Eq insert = \@Dict { metadata, dataIndices, data, size }, key, value -> hashKey = createLowLevelHasher PseudoRandSeed @@ -382,7 +382,7 @@ insert = \@Dict { metadata, dataIndices, data, size }, key, value -> ## |> Dict.len ## |> Bool.isEq 0 ## ``` -remove : Dict k v, k -> Dict k v | k implements Hash & Eq +remove : Dict k v, k -> Dict k v where k implements Hash & Eq remove = \@Dict { metadata, dataIndices, data, size }, key -> # TODO: change this from swap remove to tombstone and test is performance is still good. hashKey = @@ -426,7 +426,7 @@ remove = \@Dict { metadata, dataIndices, data, size }, key -> ## expect Dict.update (Dict.single "a" Bool.false) "a" alterValue == Dict.single "a" Bool.true ## expect Dict.update (Dict.single "a" Bool.true) "a" alterValue == Dict.empty {} ## ``` -update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v | k implements Hash & Eq +update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v where k implements Hash & Eq update = \dict, key, alter -> # TODO: look into optimizing by merging substeps and reducing lookups. possibleValue = @@ -449,7 +449,7 @@ update = \dict, key, alter -> ## |> Dict.toList ## |> Bool.isEq [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")] ## ``` -toList : Dict k v -> List (k, v) | k implements Hash & Eq +toList : Dict k v -> List (k, v) where k implements Hash & Eq toList = \@Dict { data } -> data @@ -464,7 +464,7 @@ toList = \@Dict { data } -> ## |> Dict.keys ## |> Bool.isEq [1,2,3,4] ## ``` -keys : Dict k v -> List k | k implements Hash & Eq +keys : Dict k v -> List k where k implements Hash & Eq keys = \@Dict { data } -> List.map data (\(k, _) -> k) @@ -479,7 +479,7 @@ keys = \@Dict { data } -> ## |> Dict.values ## |> Bool.isEq ["One","Two","Three","Four"] ## ``` -values : Dict k v -> List v | k implements Hash & Eq +values : Dict k v -> List v where k implements Hash & Eq values = \@Dict { data } -> List.map data (\(_, v) -> v) @@ -507,7 +507,7 @@ values = \@Dict { data } -> ## expect ## Dict.insertAll first second == expected ## ``` -insertAll : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq +insertAll : Dict k v, Dict k v -> Dict k v where k implements Hash & Eq insertAll = \xs, ys -> walk ys xs insert @@ -529,7 +529,7 @@ insertAll = \xs, ys -> ## ## expect Dict.keepShared first second == first ## ``` -keepShared : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq +keepShared : Dict k v, Dict k v -> Dict k v where k implements Hash & Eq keepShared = \xs, ys -> walk xs @@ -561,11 +561,11 @@ keepShared = \xs, ys -> ## ## expect Dict.removeAll first second == expected ## ``` -removeAll : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq +removeAll : Dict k v, Dict k v -> Dict k v where k implements Hash & Eq removeAll = \xs, ys -> walk ys xs (\state, k, _ -> remove state k) -swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k implements Hash & Eq +swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v where k implements Hash & Eq swapAndUpdateDataIndex = \@Dict { metadata, dataIndices, data, size }, removedIndex, lastIndex -> (key, _) = listGetUnsafe data lastIndex hashKey = @@ -629,7 +629,7 @@ nextEmptyOrDeletedHelper = \metadata, probe, offset -> # TODO: investigate if this needs to be split into more specific helper functions. # There is a chance that returning specific sub-info like the value would be faster. -findIndexHelper : List I8, List Nat, List (k, v), I8, k, Probe, Nat -> Result Nat [NotFound] | k implements Hash & Eq +findIndexHelper : List I8, List Nat, List (k, v), I8, k, Probe, Nat -> Result Nat [NotFound] where k implements Hash & Eq findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset -> # For finding a value, we must search past all deleted element tombstones. index = Num.addWrap (mul8 probe.slotIndex) offset @@ -661,7 +661,7 @@ findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset -> # This is how we grow the container. # If we aren't to the load factor yet, just ignore this. # The container must have an updated size including any elements about to be inserted. -maybeRehash : Dict k v -> Dict k v | k implements Hash & Eq +maybeRehash : Dict k v -> Dict k v where k implements Hash & Eq maybeRehash = \@Dict { metadata, dataIndices, data, size } -> cap = List.len dataIndices maxLoadCap = @@ -674,7 +674,7 @@ maybeRehash = \@Dict { metadata, dataIndices, data, size } -> @Dict { metadata, dataIndices, data, size } # TODO: switch rehash to iterate data and eventually clear out tombstones as well. -rehash : Dict k v -> Dict k v | k implements Hash & Eq +rehash : Dict k v -> Dict k v where k implements Hash & Eq rehash = \@Dict { metadata, dataIndices, data, size } -> newLen = 2 * List.len dataIndices newDict = @@ -687,7 +687,7 @@ rehash = \@Dict { metadata, dataIndices, data, size } -> rehashHelper newDict metadata dataIndices data 0 -rehashHelper : Dict k v, List I8, List Nat, List (k, v), Nat -> Dict k v | k implements Hash & Eq +rehashHelper : Dict k v, List I8, List Nat, List (k, v), Nat -> Dict k v where k implements Hash & Eq rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> when List.get oldMetadata index is Ok md -> @@ -708,7 +708,7 @@ rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index -> # Walked entire list, complete now. dict -insertForRehash : Dict k v, k, Nat -> Dict k v | k implements Hash & Eq +insertForRehash : Dict k v, k, Nat -> Dict k v where k implements Hash & Eq insertForRehash = \@Dict { metadata, dataIndices, data, size }, key, dataIndex -> hashKey = createLowLevelHasher PseudoRandSeed diff --git a/crates/compiler/builtins/roc/Encode.roc b/crates/compiler/builtins/roc/Encode.roc index b20e22428ac..af8b0307c1e 100644 --- a/crates/compiler/builtins/roc/Encode.roc +++ b/crates/compiler/builtins/roc/Encode.roc @@ -47,40 +47,40 @@ interface Encode Bool.{ Bool }, ] -Encoder fmt := List U8, fmt -> List U8 | fmt implements EncoderFormatting +Encoder fmt := List U8, fmt -> List U8 where fmt implements EncoderFormatting Encoding implements - toEncoder : val -> Encoder fmt | val implements Encoding, fmt implements EncoderFormatting + toEncoder : val -> Encoder fmt where val implements Encoding, fmt implements EncoderFormatting EncoderFormatting implements - u8 : U8 -> Encoder fmt | fmt implements EncoderFormatting - u16 : U16 -> Encoder fmt | fmt implements EncoderFormatting - u32 : U32 -> Encoder fmt | fmt implements EncoderFormatting - u64 : U64 -> Encoder fmt | fmt implements EncoderFormatting - u128 : U128 -> Encoder fmt | fmt implements EncoderFormatting - i8 : I8 -> Encoder fmt | fmt implements EncoderFormatting - i16 : I16 -> Encoder fmt | fmt implements EncoderFormatting - i32 : I32 -> Encoder fmt | fmt implements EncoderFormatting - i64 : I64 -> Encoder fmt | fmt implements EncoderFormatting - i128 : I128 -> Encoder fmt | fmt implements EncoderFormatting - f32 : F32 -> Encoder fmt | fmt implements EncoderFormatting - f64 : F64 -> Encoder fmt | fmt implements EncoderFormatting - dec : Dec -> Encoder fmt | fmt implements EncoderFormatting - bool : Bool -> Encoder fmt | fmt implements EncoderFormatting - string : Str -> Encoder fmt | fmt implements EncoderFormatting - list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting - record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt implements EncoderFormatting - tuple : List (Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting - tag : Str, List (Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting + u8 : U8 -> Encoder fmt where fmt implements EncoderFormatting + u16 : U16 -> Encoder fmt where fmt implements EncoderFormatting + u32 : U32 -> Encoder fmt where fmt implements EncoderFormatting + u64 : U64 -> Encoder fmt where fmt implements EncoderFormatting + u128 : U128 -> Encoder fmt where fmt implements EncoderFormatting + i8 : I8 -> Encoder fmt where fmt implements EncoderFormatting + i16 : I16 -> Encoder fmt where fmt implements EncoderFormatting + i32 : I32 -> Encoder fmt where fmt implements EncoderFormatting + i64 : I64 -> Encoder fmt where fmt implements EncoderFormatting + i128 : I128 -> Encoder fmt where fmt implements EncoderFormatting + f32 : F32 -> Encoder fmt where fmt implements EncoderFormatting + f64 : F64 -> Encoder fmt where fmt implements EncoderFormatting + dec : Dec -> Encoder fmt where fmt implements EncoderFormatting + bool : Bool -> Encoder fmt where fmt implements EncoderFormatting + string : Str -> Encoder fmt where fmt implements EncoderFormatting + list : List elem, (elem -> Encoder fmt) -> Encoder fmt where fmt implements EncoderFormatting + record : List { key : Str, value : Encoder fmt } -> Encoder fmt where fmt implements EncoderFormatting + tuple : List (Encoder fmt) -> Encoder fmt where fmt implements EncoderFormatting + tag : Str, List (Encoder fmt) -> Encoder fmt where fmt implements EncoderFormatting -custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt implements EncoderFormatting +custom : (List U8, fmt -> List U8) -> Encoder fmt where fmt implements EncoderFormatting custom = \encoder -> @Encoder encoder -appendWith : List U8, Encoder fmt, fmt -> List U8 | fmt implements EncoderFormatting +appendWith : List U8, Encoder fmt, fmt -> List U8 where fmt implements EncoderFormatting appendWith = \lst, @Encoder doEncoding, fmt -> doEncoding lst fmt -append : List U8, val, fmt -> List U8 | val implements Encoding, fmt implements EncoderFormatting +append : List U8, val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting append = \lst, val, fmt -> appendWith lst (toEncoder val) fmt -toBytes : val, fmt -> List U8 | val implements Encoding, fmt implements EncoderFormatting +toBytes : val, fmt -> List U8 where val implements Encoding, fmt implements EncoderFormatting toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index 3bbff810d58..d96f1c5eb0b 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -33,7 +33,7 @@ Hash implements ## Hashes a value into a [Hasher]. ## Note that [hash] does not produce a hash value itself; the hasher must be ## [complete]d in order to extract the hash value. - hash : hasher, a -> hasher | a implements Hash, hasher implements Hasher + hash : hasher, a -> hasher where a implements Hash, hasher implements Hasher ## Describes a hashing algorithm that is fed bytes and produces an integer hash. ## @@ -42,26 +42,26 @@ Hash implements ## cryptographically-secure hashing. Hasher implements ## Adds a list of bytes to the hasher. - addBytes : a, List U8 -> a | a implements Hasher + addBytes : a, List U8 -> a where a implements Hasher ## Adds a single U8 to the hasher. - addU8 : a, U8 -> a | a implements Hasher + addU8 : a, U8 -> a where a implements Hasher ## Adds a single U16 to the hasher. - addU16 : a, U16 -> a | a implements Hasher + addU16 : a, U16 -> a where a implements Hasher ## Adds a single U32 to the hasher. - addU32 : a, U32 -> a | a implements Hasher + addU32 : a, U32 -> a where a implements Hasher ## Adds a single U64 to the hasher. - addU64 : a, U64 -> a | a implements Hasher + addU64 : a, U64 -> a where a implements Hasher ## Adds a single U128 to the hasher. - addU128 : a, U128 -> a | a implements Hasher + addU128 : a, U128 -> a where a implements Hasher ## Completes the hasher, extracting a hash value from its ## accumulated hash state. - complete : a -> U64 | a implements Hasher + complete : a -> U64 where a implements Hasher ## Adds a string into a [Hasher] by hashing its UTF-8 bytes. hashStrBytes = \hasher, s -> @@ -73,33 +73,33 @@ hashList = \hasher, lst -> hash accumHasher elem ## Adds a single [Bool] to a hasher. -hashBool : a, Bool -> a | a implements Hasher +hashBool : a, Bool -> a where a implements Hasher hashBool = \hasher, b -> asU8 = if b then 1 else 0 addU8 hasher asU8 ## Adds a single I8 to a hasher. -hashI8 : a, I8 -> a | a implements Hasher +hashI8 : a, I8 -> a where a implements Hasher hashI8 = \hasher, n -> addU8 hasher (Num.toU8 n) ## Adds a single I16 to a hasher. -hashI16 : a, I16 -> a | a implements Hasher +hashI16 : a, I16 -> a where a implements Hasher hashI16 = \hasher, n -> addU16 hasher (Num.toU16 n) ## Adds a single I32 to a hasher. -hashI32 : a, I32 -> a | a implements Hasher +hashI32 : a, I32 -> a where a implements Hasher hashI32 = \hasher, n -> addU32 hasher (Num.toU32 n) ## Adds a single I64 to a hasher. -hashI64 : a, I64 -> a | a implements Hasher +hashI64 : a, I64 -> a where a implements Hasher hashI64 = \hasher, n -> addU64 hasher (Num.toU64 n) ## Adds a single I128 to a hasher. -hashI128 : a, I128 -> a | a implements Hasher +hashI128 : a, I128 -> a where a implements Hasher hashI128 = \hasher, n -> addU128 hasher (Num.toU128 n) ## Adds a single Nat to a hasher. -hashNat : a, Nat -> a | a implements Hasher +hashNat : a, Nat -> a where a implements Hasher hashNat = \hasher, n -> isPlatform32bit = x : Nat @@ -117,7 +117,7 @@ hashNat = \hasher, n -> i128OfDec : Dec -> I128 ## Adds a single [Dec] to a hasher. -hashDec : a, Dec -> a | a implements Hasher +hashDec : a, Dec -> a where a implements Hasher hashDec = \hasher, n -> hashI128 hasher (i128OfDec n) ## Adds a container of [Hash]able elements to a [Hasher] by hashing each element. diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index 5e3259fc784..c713dff612d 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -363,7 +363,7 @@ join = \lists -> List.walk lists (List.withCapacity totalLength) (\state, list -> List.concat state list) -contains : List a, a -> Bool | a implements Eq +contains : List a, a -> Bool where a implements Eq contains = \list, needle -> List.any list (\x -> x == needle) @@ -1037,7 +1037,7 @@ intersperse = \list, sep -> ## is considered to "start with" an empty list. ## ## If the first list is empty, this only returns `Bool.true` if the second list is empty. -startsWith : List elem, List elem -> Bool | elem implements Eq +startsWith : List elem, List elem -> Bool where elem implements Eq startsWith = \list, prefix -> # TODO once we have seamless slices, verify that this wouldn't # have better performance with a function like List.compareSublists @@ -1049,7 +1049,7 @@ startsWith = \list, prefix -> ## is considered to "end with" an empty list. ## ## If the first list is empty, this only returns `Bool.true` if the second list is empty. -endsWith : List elem, List elem -> Bool | elem implements Eq +endsWith : List elem, List elem -> Bool where elem implements Eq endsWith = \list, suffix -> # TODO once we have seamless slices, verify that this wouldn't # have better performance with a function like List.compareSublists @@ -1079,7 +1079,7 @@ split = \elements, userSplitIndex -> ## ``` ## List.splitFirst [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo], after: [Bar, Z, Baz] } ## ``` -splitFirst : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem implements Eq +splitFirst : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq splitFirst = \list, delimiter -> when List.findFirstIndex list (\elem -> elem == delimiter) is Ok index -> @@ -1095,7 +1095,7 @@ splitFirst = \list, delimiter -> ## ``` ## List.splitLast [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo, Z, Bar], after: [Baz] } ## ``` -splitLast : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem implements Eq +splitLast : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] where elem implements Eq splitLast = \list, delimiter -> when List.findLastIndex list (\elem -> elem == delimiter) is Ok index -> diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index 4d08af15bfc..53871d45a05 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -25,7 +25,7 @@ interface Set ## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) ## type which stores a collection of unique values, without any ordering -Set k := Dict.Dict k {} | k implements Hash & Eq +Set k := Dict.Dict k {} where k implements Hash & Eq implements [ Eq { isEq, @@ -35,7 +35,7 @@ Set k := Dict.Dict k {} | k implements Hash & Eq }, ] -isEq : Set k, Set k -> Bool | k implements Hash & Eq +isEq : Set k, Set k -> Bool where k implements Hash & Eq isEq = \xs, ys -> if len xs != len ys then Bool.false @@ -46,7 +46,7 @@ isEq = \xs, ys -> else Break Bool.false -hashSet : hasher, Set k -> hasher | k implements Hash & Eq, hasher implements Hasher +hashSet : hasher, Set k -> hasher where k implements Hash & Eq, hasher implements Hasher hashSet = \hasher, @Set inner -> Hash.hash hasher inner ## Creates a new empty `Set`. @@ -56,7 +56,7 @@ hashSet = \hasher, @Set inner -> Hash.hash hasher inner ## ## expect countValues == 0 ## ``` -empty : {} -> Set k | k implements Hash & Eq +empty : {} -> Set k where k implements Hash & Eq empty = \{} -> @Set (Dict.empty {}) ## Creates a new `Set` with a single value. @@ -66,7 +66,7 @@ empty = \{} -> @Set (Dict.empty {}) ## ## expect countValues == 1 ## ``` -single : k -> Set k | k implements Hash & Eq +single : k -> Set k where k implements Hash & Eq single = \key -> Dict.single key {} |> @Set @@ -82,7 +82,7 @@ single = \key -> ## ## expect countValues == 3 ## ``` -insert : Set k, k -> Set k | k implements Hash & Eq +insert : Set k, k -> Set k where k implements Hash & Eq insert = \@Set dict, key -> Dict.insert dict key {} |> @Set @@ -115,7 +115,7 @@ expect ## ## expect countValues == 3 ## ``` -len : Set k -> Nat | k implements Hash & Eq +len : Set k -> Nat where k implements Hash & Eq len = \@Set dict -> Dict.len dict @@ -145,7 +145,7 @@ expect ## expect has10 == Bool.false ## expect has20 == Bool.true ## ``` -remove : Set k, k -> Set k | k implements Hash & Eq +remove : Set k, k -> Set k where k implements Hash & Eq remove = \@Set dict, key -> Dict.remove dict key |> @Set @@ -164,7 +164,7 @@ remove = \@Set dict, key -> ## expect hasApple == Bool.true ## expect hasBanana == Bool.false ## ``` -contains : Set k, k -> Bool | k implements Hash & Eq +contains : Set k, k -> Bool where k implements Hash & Eq contains = \@Set dict, key -> Dict.contains dict key @@ -177,7 +177,7 @@ contains = \@Set dict, key -> ## ## expect Set.toList numbers == values ## ``` -toList : Set k -> List k | k implements Hash & Eq +toList : Set k -> List k where k implements Hash & Eq toList = \@Set dict -> Dict.keys dict @@ -191,7 +191,7 @@ toList = \@Set dict -> ## ## expect Set.fromList [Pear, Apple, Banana] == values ## ``` -fromList : List k -> Set k | k implements Hash & Eq +fromList : List k -> Set k where k implements Hash & Eq fromList = \list -> initial = @Set (Dict.withCapacity (List.len list)) @@ -207,7 +207,7 @@ fromList = \list -> ## ## expect Set.union set1 set2 == Set.fromList [Left, Right] ## ``` -union : Set k, Set k -> Set k | k implements Hash & Eq +union : Set k, Set k -> Set k where k implements Hash & Eq union = \@Set dict1, @Set dict2 -> Dict.insertAll dict1 dict2 |> @Set @@ -220,7 +220,7 @@ union = \@Set dict1, @Set dict2 -> ## ## expect Set.intersection set1 set2 == Set.single Left ## ``` -intersection : Set k, Set k -> Set k | k implements Hash & Eq +intersection : Set k, Set k -> Set k where k implements Hash & Eq intersection = \@Set dict1, @Set dict2 -> Dict.keepShared dict1 dict2 |> @Set @@ -234,7 +234,7 @@ intersection = \@Set dict1, @Set dict2 -> ## ## expect Set.difference first second == Set.fromList [Up, Down] ## ``` -difference : Set k, Set k -> Set k | k implements Hash & Eq +difference : Set k, Set k -> Set k where k implements Hash & Eq difference = \@Set dict1, @Set dict2 -> Dict.removeAll dict1 dict2 |> @Set @@ -257,7 +257,7 @@ difference = \@Set dict1, @Set dict2 -> ## ## expect result == 2 ## ``` -walk : Set k, state, (state, k -> state) -> state | k implements Hash & Eq +walk : Set k, state, (state, k -> state) -> state where k implements Hash & Eq walk = \@Set dict, state, step -> Dict.walk dict state (\s, k, _ -> step s k) @@ -276,7 +276,7 @@ walk = \@Set dict, state, step -> ## ## expect result == FoundTheAnswer ## ``` -walkUntil : Set k, state, (state, k -> [Continue state, Break state]) -> state | k implements Hash & Eq +walkUntil : Set k, state, (state, k -> [Continue state, Break state]) -> state where k implements Hash & Eq walkUntil = \@Set dict, state, step -> Dict.walkUntil dict state (\s, k, _ -> step s k) diff --git a/crates/compiler/can/src/abilities.rs b/crates/compiler/can/src/abilities.rs index 26d5643c9a5..43bef5f8a68 100644 --- a/crates/compiler/can/src/abilities.rs +++ b/crates/compiler/can/src/abilities.rs @@ -80,7 +80,7 @@ impl AbilityMemberData { /// Solved lambda sets for an ability member specialization. For example, if we have /// -/// Default implements default : {} -[[] + a:default:1]-> a | a implements Default +/// Default implements default : {} -[[] + a:default:1]-> a where a implements Default /// /// A := {} /// default = \{} -[[closA]]-> @A {} @@ -144,7 +144,7 @@ pub struct IAbilitiesStore { /// /// For example, in the program /// - /// Hash implements hash : a -> U64 | a implements Hash + /// Hash implements hash : a -> U64 where a implements Hash /// /// Id := {} implements [Hash {hash: myHash}] /// myHash = \@Id n -> n @@ -284,7 +284,7 @@ impl IAbilitiesStore { } /// 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 implements Hash`. + /// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 where 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 { /// 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 implements Hash`. + /// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 where 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( diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 3bd138657f1..758c058a92d 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -510,7 +510,7 @@ fn canonicalize_claimed_ability_impl<'a>( // definition symbol, for example when the ability is defined in the same // module as an implementer: // - // Eq implements eq : a, a -> U64 | a implements Eq + // Eq implements eq : a, a -> U64 where a implements Eq // // A := U8 implements [Eq {eq}] // @@ -1398,7 +1398,7 @@ fn resolve_abilities( } [..] => { // There is more than one variable bound to the member signature, so something like - // Eq implements eq : a, b -> Bool | a implements Eq, b implements Eq + // Eq implements eq : a, b -> Bool where a implements 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( diff --git a/crates/compiler/can/src/pattern.rs b/crates/compiler/can/src/pattern.rs index 5541ab47106..565d57fca9b 100644 --- a/crates/compiler/can/src/pattern.rs +++ b/crates/compiler/can/src/pattern.rs @@ -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 implements Hash`, + /// For example, given an ability member definition `hash : a -> U64 where 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 { diff --git a/crates/compiler/can/src/scope.rs b/crates/compiler/can/src/scope.rs index 678714999bd..e0b847c56ef 100644 --- a/crates/compiler/can/src/scope.rs +++ b/crates/compiler/can/src/scope.rs @@ -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 implements eq : a, a -> Bool | a implements Eq` gets a shadow symbol it can use for its + /// member `Eq implements eq : a, a -> Bool where a implements Eq` gets a shadow symbol it can use for its /// implementation. /// /// Only one shadow of an ability member is permitted per scope. diff --git a/crates/compiler/derive/src/decoding.rs b/crates/compiler/derive/src/decoding.rs index acd58680b25..9f0b29c8071 100644 --- a/crates/compiler/derive/src/decoding.rs +++ b/crates/compiler/derive/src/decoding.rs @@ -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 implements DecoderFormatting + // Decode.decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val where 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 implements DecoderFormatting + // List U8, Decoder val fmt, fmt -> DecodeResult val where 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 implements DecoderFormatting + // (List U8, fmt -> DecodeResult val) -> Decoder val fmt where 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 implements DecoderFormatting + // (List U8, fmt -> DecodeResult val) -> Decoder val fmt where fmt implements DecoderFormatting // ~ (List U8, fmt -> DecodeResult (List elem)) -> Decoder (List elem) fmt env.unify(decode_custom_type, this_decode_custom_fn_var); diff --git a/crates/compiler/derive/src/decoding/list.rs b/crates/compiler/derive/src/decoding/list.rs index 59fe3e091bf..ed2cd66de8b 100644 --- a/crates/compiler/derive/src/decoding/list.rs +++ b/crates/compiler/derive/src/decoding/list.rs @@ -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 implements Decoding, fmt implements DecoderFormatting + // def_symbol : Decoder (List elem) fmt where elem implements 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 implements Decoding, fmt implements EncoderFormatting + // Decode.decoder : Decoder elem fmt where elem implements Decoding, fmt implements EncoderFormatting let (elem_decoder, elem_decoder_var) = { // build `Decode.decoder : Decoder elem fmt` type - // Decoder val fmt | val implements Decoding, fmt implements EncoderFormatting + // Decoder val fmt where val implements 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 implements DecoderFormatting + // Decoder val fmt -[uls]-> Decoder (List val) fmt where 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 implements DecoderFormatting + // Decoder val fmt -[uls]-> Decoder (List val) fmt where fmt implements DecoderFormatting // ~ Decoder elem fmt -a -> b env.unify(decode_list_fn_var, this_decode_list_fn_var); diff --git a/crates/compiler/derive/src/decoding/record.rs b/crates/compiler/derive/src/decoding/record.rs index 8549df9f7d8..adc01960026 100644 --- a/crates/compiler/derive/src/decoding/record.rs +++ b/crates/compiler/derive/src/decoding/record.rs @@ -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 implements Decoding, b implements Decoding, fmt implements DecoderFormatting +/// decoder : Decoder {first: a, second: b} fmt where 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} diff --git a/crates/compiler/derive/src/decoding/tuple.rs b/crates/compiler/derive/src/decoding/tuple.rs index 15e9666427f..a327bdfded1 100644 --- a/crates/compiler/derive/src/decoding/tuple.rs +++ b/crates/compiler/derive/src/decoding/tuple.rs @@ -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 implements Decoding, b implements Decoding, fmt implements DecoderFormatting +/// decoder : Decoder (a, b) fmt where 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} diff --git a/crates/compiler/derive/src/encoding.rs b/crates/compiler/derive/src/encoding.rs index 959d8a8a43e..ccade769369 100644 --- a/crates/compiler/derive/src/encoding.rs +++ b/crates/compiler/derive/src/encoding.rs @@ -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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // toEncoder : (typeof rcd.a) -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // List e, (e -> Encoder fmt) -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // List e, (e -> Encoder fmt) -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // Encode.list : List elem, to_elem_encoder_fn_var -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // toEncoder : (typeof rcd.a) -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // List { key : Str, value : Encoder fmt } -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // List { key : Str, value : Encoder fmt } -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // Encode.record : fields_list_var -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // toEncoder : (typeof tup.0) -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // List (Encoder fmt) -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // List (Encoder fmt) -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // Encode.tuple : elem_encoders_list_var -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // expected: val -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // val -[uls]-> Encoder fmt where fmt implements EncoderFormatting // ~ t1 -[clos]-> t' env.unify(to_encoder_fn_var, this_to_encoder_fn_var); - // toEncoder : t1 -[clos]-> Encoder fmt | fmt implements EncoderFormatting + // toEncoder : t1 -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // expected: Str, List (Encoder fmt) -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // Str, List (Encoder fmt) -[uls]-> Encoder fmt where 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 implements EncoderFormatting + // Encode.tag : Str, List whole_encoders_var -[clos]-> Encoder fmt where 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 implements EncoderFormatting + // fmt: fmt where 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 implements EncoderFormatting + // expected: Encode.appendWith : List U8, Encoder fmt, fmt -[appendWith]-> List U8 where 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 implements EncoderFormatting + // wanted: Encode.appendWith : List U8, encoder_var, fmt -[clos]-> List U8 where 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 implements EncoderFormatting - // ~ List U8, encoder_var, fmt -[clos]-> List U8 | fmt implements EncoderFormatting + // List U8, Encoder fmt, fmt -[appendWith]-> List U8 where fmt implements EncoderFormatting + // ~ List U8, encoder_var, fmt -[clos]-> List U8 where 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 implements EncoderFormatting + // Encode.appendWith : List U8, encoder_var, fmt -[appendWith]-> List U8 where 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 implements EncoderFormatting + // expected: Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt where 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 implements EncoderFormatting + // (List U8, fmt -> List U8) -[..]-> Encoder fmt where 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 implements EncoderFormatting + // Encode.custom : (List U8, fmt -> List U8) -> Encoder fmt where fmt implements EncoderFormatting let custom_fn = Box::new(( this_custom_fn_var, Loc::at_zero(Var(Symbol::ENCODE_CUSTOM, this_custom_fn_var)), diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index d0fff82ceed..0580f16a3b5 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -75,7 +75,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (V // Now, a hasher for this record is // - // hash_rcd : hasher, { f1: t1, ..., fn: tn } -> hasher | hasher implements Hasher + // hash_rcd : hasher, { f1: t1, ..., fn: tn } -> hasher where 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 implements Hasher + // hash_tup : hasher, (t1, ..., tn) -> hasher where 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 implements Hasher + // hash_union : hasher, [ A t11 .. t1n, ..., Q tq1 .. tqm ] -> hasher where 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 implements Hasher + // hash_union : hasher, [ A t1 .. tn ] -> hasher where 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 implements Hasher, val implements Hash + // hasher, val -[uls]-> hasher where hasher implements 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 implements Hasher, val implements Hash + // hasher, val -[uls]-> hasher where hasher implements 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 implements Hasher, (typeof field) implements Hash + // Hash.hash : hasher, (typeof field) -[clos]-> hasher where hasher implements 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, diff --git a/crates/compiler/derive/src/util.rs b/crates/compiler/derive/src/util.rs index 1dfc38f89fd..8403866721e 100644 --- a/crates/compiler/derive/src/util.rs +++ b/crates/compiler/derive/src/util.rs @@ -130,7 +130,7 @@ impl Env<'_> { }) .collect(); - // Since we're doing `{foo} ~ a | a implements Encoding`, we may see "lambda sets to + // Since we're doing `{foo} ~ a where 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! // diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index 472ff3ed9c9..56762d9c319 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -350,16 +350,23 @@ impl<'a> Formattable for TypeAnnotation<'a> { } } - Where(annot, has_clauses) => { + Where(annot, implements_clauses) => { annot.format_with_options(buf, parens, newlines, indent); - if has_clauses.iter().any(|has| has.is_multiline()) { + if implements_clauses + .iter() + .any(|implements| implements.is_multiline()) + { buf.newline(); buf.indent(indent); } else { buf.spaces(1); } - for (i, has) in has_clauses.iter().enumerate() { - buf.push(if i == 0 { '|' } else { ',' }); + for (i, has) in implements_clauses.iter().enumerate() { + buf.push_str(if i == 0 { + roc_parse::keyword::WHERE + } else { + "," + }); buf.spaces(1); has.format_with_options(buf, parens, newlines, indent); } diff --git a/crates/compiler/fmt/src/def.rs b/crates/compiler/fmt/src/def.rs index c71d327d9cd..a391b11f49c 100644 --- a/crates/compiler/fmt/src/def.rs +++ b/crates/compiler/fmt/src/def.rs @@ -133,7 +133,7 @@ impl<'a> Formattable for TypeDef<'a> { fmt_pattern(buf, &var.value, indent, Parens::NotNeeded); buf.indent(indent); } - buf.push(' '); + buf.spaces(1); buf.push_str(roc_parse::keyword::IMPLEMENTS); if !self.is_multiline() { diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 81d5b48a5c1..31cef9057f5 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -3171,7 +3171,7 @@ fn update<'a>( // # Default module // interface Default exposes [default, getDefault] // - // Default implements default : {} -> a | a implements Default + // Default implements default : {} -> a where a implements Default // // getDefault = \{} -> default {} // diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc b/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc index 155d9ec8045..b9b44ddbd61 100644 --- a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc +++ b/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc @@ -13,7 +13,7 @@ Model position : } -initialModel : position -> Model position | position implements Hash & Eq +initialModel : position -> Model position where position implements Hash & Eq initialModel = \start -> { evaluated : Set.empty {} , openSet : Set.single start @@ -22,7 +22,7 @@ initialModel = \start -> } -cheapestOpen : (position -> F64), Model position -> Result position [KeyNotFound] | position implements Hash & Eq +cheapestOpen : (position -> F64), Model position -> Result position [KeyNotFound] where position implements Hash & Eq cheapestOpen = \costFunction, model -> folder = \resSmallestSoFar, position -> @@ -47,7 +47,7 @@ cheapestOpen = \costFunction, model -> -reconstructPath : Dict position position, position -> List position | position implements Hash & Eq +reconstructPath : Dict position position, position -> List position where position implements Hash & Eq reconstructPath = \cameFrom, goal -> when Dict.get cameFrom goal is Err KeyNotFound -> @@ -56,7 +56,7 @@ reconstructPath = \cameFrom, goal -> Ok next -> List.append (reconstructPath cameFrom next) goal -updateCost : position, position, Model position -> Model position | position implements Hash & Eq +updateCost : position, position, Model position -> Model position where position implements Hash & Eq updateCost = \current, neighbour, model -> newCameFrom = Dict.insert model.cameFrom neighbour current @@ -80,12 +80,12 @@ updateCost = \current, neighbour, model -> model -findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [KeyNotFound] | position implements Hash & Eq +findPath : { costFunction: (position, position -> F64), moveFunction: (position -> Set position), start : position, end : position } -> Result (List position) [KeyNotFound] where position implements Hash & Eq findPath = \{ costFunction, moveFunction, start, end } -> astar costFunction moveFunction end (initialModel start) -astar : (position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] | position implements Hash & Eq +astar : (position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] where position implements Hash & Eq astar = \costFn, moveFn, goal, model -> when cheapestOpen (\position -> costFn goal position) model is Err _ -> diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index 7aa625372db..5a770d0cb4f 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -491,12 +491,12 @@ fn load_astar() { expect_types( loaded_module, hashmap! { - "findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [KeyNotFound] | position implements Hash & Eq", - "initialModel" => "position -> Model position | position implements Hash & Eq", - "reconstructPath" => "Dict position position, position -> List position | position implements Hash & Eq", - "updateCost" => "position, position, Model position -> Model position | position implements Hash & Eq", - "cheapestOpen" => "(position -> F64), Model position -> Result position [KeyNotFound] | position implements Hash & Eq", - "astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] | position implements Hash & Eq", + "findPath" => "{ costFunction : position, position -> F64, end : position, moveFunction : position -> Set position, start : position } -> Result (List position) [KeyNotFound] where position implements Hash & Eq", + "initialModel" => "position -> Model position where position implements Hash & Eq", + "reconstructPath" => "Dict position position, position -> List position where position implements Hash & Eq", + "updateCost" => "position, position, Model position -> Model position where position implements Hash & Eq", + "cheapestOpen" => "(position -> F64), Model position -> Result position [KeyNotFound] where position implements Hash & Eq", + "astar" => "(position, position -> F64), (position -> Set position), position, Model position -> [Err [KeyNotFound], Ok (List position)] where position implements Hash & Eq", }, ); } diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 88e6db42107..662d5de071f 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -365,7 +365,7 @@ pub enum Implements<'a> { SpaceAfter(&'a Implements<'a>, &'a [CommentOrNewline<'a>]), } -/// An ability demand is a value defining the ability; for example `hash : a -> U64 | a implements Hash` +/// An ability demand is a value defining the ability; for example `hash : a -> U64 where a implements Hash` /// for a `Hash` ability. #[derive(Debug, Clone, Copy, PartialEq)] pub struct AbilityMember<'a> { @@ -399,7 +399,7 @@ pub enum TypeDef<'a> { /// An ability definition. E.g. /// Hash implements - /// hash : a -> U64 | a implements Hash + /// hash : a -> U64 where a implements Hash Ability { header: TypeHeader<'a>, loc_implements: Loc>, @@ -641,7 +641,7 @@ pub enum TypeAnnotation<'a> { /// The `*` type variable, e.g. in (List *) Wildcard, - /// A "where" clause demanding abilities designated by a `|`, e.g. `a -> U64 | a implements Hash` + /// A "where" clause demanding abilities designated by a `where`, e.g. `a -> U64 where a implements Hash` Where(&'a Loc>, &'a [Loc>]), // We preserve this for the formatter; canonicalization ignores it. diff --git a/crates/compiler/parse/src/keyword.rs b/crates/compiler/parse/src/keyword.rs index e37f0c5e5c9..102fd43a7cc 100644 --- a/crates/compiler/parse/src/keyword.rs +++ b/crates/compiler/parse/src/keyword.rs @@ -14,4 +14,6 @@ pub const CRASH: &str = "crash"; pub const IMPLEMENTS: &str = "implements"; pub const WHERE: &str = "where"; -pub const KEYWORDS: [&str; 10] = [IF, THEN, ELSE, WHEN, AS, IS, DBG, EXPECT, EXPECT_FX, CRASH]; +pub const KEYWORDS: [&str; 11] = [ + IF, THEN, ELSE, WHEN, AS, IS, DBG, EXPECT, EXPECT_FX, CRASH, WHERE, +]; diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index a0fab6842ff..6f33073a66a 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -479,14 +479,16 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<' ) } -/// Parse a chain of `implements` clauses, e.g. " | a implements Hash, b implements Eq". -/// Returns the clauses and spaces before the starting "|", if there were any. +/// Parse a chain of `implements` clauses, e.g. " where a implements Hash, b implements Eq". +/// Returns the clauses and spaces before the starting "where", if there were any. fn implements_clause_chain<'a>( ) -> impl Parser<'a, (&'a [CommentOrNewline<'a>], &'a [Loc>]), EType<'a>> { move |arena, state: State<'a>, min_indent: u32| { - let (_, (spaces_before, ()), state) = - and!(space0_e(EType::TIndentStart), word1(b'|', EType::TWhereBar)) - .parse(arena, state, min_indent)?; + let (_, (spaces_before, ()), state) = and!( + space0_e(EType::TIndentStart), + word(crate::keyword::WHERE, EType::TWhereBar) + ) + .parse(arena, state, min_indent)?; // Parse the first clause (there must be one), then the rest let (_, first_clause, state) = implements_clause().parse(arena, state, min_indent)?; @@ -645,11 +647,12 @@ fn expression<'a>( // Finally, try to parse a where clause if there is one. // The where clause must be at least as deep as where the type annotation started. match implements_clause_chain().parse(arena, state.clone(), min_indent) { - Ok((where_progress, (spaces_before, has_chain), state)) => { - let region = Region::span_across(&annot.region, &has_chain.last().unwrap().region); + Ok((where_progress, (spaces_before, implements_chain), state)) => { + let region = + Region::span_across(&annot.region, &implements_chain.last().unwrap().region); let type_annot = if !spaces_before.is_empty() { - // We're transforming the spaces_before the '|' - // into spaces_after the thing before the '|' + // We're transforming the spaces_before the 'where' + // into spaces_after the thing before the 'where' let spaced = arena .alloc(annot.value) .with_spaces_after(spaces_before, annot.region); @@ -657,7 +660,7 @@ fn expression<'a>( } else { &*arena.alloc(annot) }; - let where_annot = TypeAnnotation::Where(type_annot, has_chain); + let where_annot = TypeAnnotation::Where(type_annot, implements_chain); Ok(( where_progress.or(progress), Loc::at(region, where_annot), diff --git a/crates/compiler/solve/src/ability.rs b/crates/compiler/solve/src/ability.rs index 633cdc31104..170e951f37d 100644 --- a/crates/compiler/solve/src/ability.rs +++ b/crates/compiler/solve/src/ability.rs @@ -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 implements Decode` constraint as needed. + // instead recurse here, and add a `t ~ u where u implements Decode` constraint as needed. stack.push(ext); } } diff --git a/crates/compiler/solve/src/solve.rs b/crates/compiler/solve/src/solve.rs index 72d1d3bfef4..6962907544c 100644 --- a/crates/compiler/solve/src/solve.rs +++ b/crates/compiler/solve/src/solve.rs @@ -2510,7 +2510,7 @@ impl AmbientFunctionPolicy { }), Content::FlexVar(_) => { // Something like - // Encoder fmt : List U8, fmt -a-> List U8 | fmt implements EncoderFormatting + // Encoder fmt : List U8, fmt -a-> List U8 where 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 { diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 444b7b59bcd..c5e0065c323 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -3150,7 +3150,7 @@ mod solve_expr { Dict.insert "# ), - "Dict k v, k, v -> Dict k v | k implements Hash & Eq", + "Dict k v, k, v -> Dict k v where k implements Hash & Eq", ); } @@ -3411,7 +3411,7 @@ mod solve_expr { infer_eq_without_problem( indoc!( r#" - reconstructPath : Dict position position, position -> List position | position implements Hash & Eq + reconstructPath : Dict position position, position -> List position where position implements Hash & Eq reconstructPath = \cameFrom, goal -> when Dict.get cameFrom goal is Err KeyNotFound -> @@ -3423,7 +3423,7 @@ mod solve_expr { reconstructPath "# ), - "Dict position position, position -> List position | position implements Hash & Eq", + "Dict position position, position -> List position where position implements Hash & Eq", ); } @@ -3458,7 +3458,7 @@ mod solve_expr { Model position : { openSet : Set position } - cheapestOpen : Model position -> Result position [KeyNotFound] | position implements Hash & Eq + cheapestOpen : Model position -> Result position [KeyNotFound] where position implements Hash & Eq cheapestOpen = \model -> folder = \resSmallestSoFar, position -> @@ -3473,14 +3473,14 @@ mod solve_expr { Set.walk model.openSet (Ok { position: boom {}, cost: 0.0 }) folder |> Result.map (\x -> x.position) - astar : Model position -> Result position [KeyNotFound] | position implements Hash & Eq + astar : Model position -> Result position [KeyNotFound] where position implements Hash & Eq astar = \model -> cheapestOpen model main = astar "# ), - "Model position -> Result position [KeyNotFound] | position implements Hash & Eq", + "Model position -> Result position [KeyNotFound] where position implements Hash & Eq", ); } @@ -4122,7 +4122,7 @@ mod solve_expr { Key k : Num k - removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v | k implements Hash & Eq + removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v where k implements Hash & Eq removeHelpEQGT = \targetKey, dict -> when dict is Node color key value left right -> @@ -4236,7 +4236,7 @@ mod solve_expr { _ -> Empty - removeHelp : Key k, RBTree (Key k) v -> RBTree (Key k) v | k implements Hash & Eq + removeHelp : Key k, RBTree (Key k) v -> RBTree (Key k) v where k implements Hash & Eq removeHelp = \targetKey, dict -> when dict is Empty -> @@ -4324,7 +4324,7 @@ mod solve_expr { RBTree k v : [Node NodeColor k v (RBTree k v) (RBTree k v), Empty] - removeHelp : Num k, RBTree (Num k) v -> RBTree (Num k) v | k implements Hash & Eq + removeHelp : Num k, RBTree (Num k) v -> RBTree (Num k) v where k implements Hash & Eq removeHelp = \targetKey, dict -> when dict is Empty -> @@ -4359,7 +4359,7 @@ mod solve_expr { removeHelpPrepEQGT : Key k, RBTree (Key k) v, NodeColor, (Key k), v, RBTree (Key k) v, RBTree (Key k) v -> RBTree (Key k) v - removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v | k implements Hash & Eq + removeHelpEQGT : Key k, RBTree (Key k) v -> RBTree (Key k) v where k implements Hash & Eq removeHelpEQGT = \targetKey, dict -> when dict is Node color key value left right -> diff --git a/crates/compiler/test_derive/src/decoding.rs b/crates/compiler/test_derive/src/decoding.rs index b9c024ec660..edba290303a 100644 --- a/crates/compiler/test_derive/src/decoding.rs +++ b/crates/compiler/test_derive/src/decoding.rs @@ -106,8 +106,8 @@ fn list() { derive_test(Decoder, v!(Symbol::LIST_LIST v!(STR)), |golden| { assert_snapshot!(golden, @r###" # derived for List Str - # Decoder (List val) fmt | fmt implements DecoderFormatting, val implements Decoding - # List U8, fmt -[[custom(3)]]-> { rest : List U8, result : [Err [TooShort], Ok (List val)] } | fmt implements DecoderFormatting, val implements Decoding + # Decoder (List val) fmt where fmt implements DecoderFormatting, val implements Decoding + # List U8, fmt -[[custom(3)]]-> { rest : List U8, result : [Err [TooShort], Ok (List val)] } where fmt implements DecoderFormatting, val implements Decoding # Specialization lambda sets: # @<1>: [[custom(3)]] #Derived.decoder_list = @@ -124,8 +124,8 @@ fn record_2_fields() { derive_test(Decoder, v!({first: v!(STR), second: v!(STR),}), |golden| { assert_snapshot!(golden, @r###" # derived for { first : Str, second : Str } - # Decoder { first : val, second : val1 } fmt | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding + # Decoder { first : val, second : val1 } fmt where fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok { first : val, second : val1 }] } where fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_{first,second} = @@ -181,8 +181,8 @@ fn tuple_2_fields() { derive_test(Decoder, v!((v!(STR), v!(U8),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( Str, U8 )* - # Decoder ( val, val1 )* fmt | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding - # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } | fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding + # Decoder ( val, val1 )* fmt where fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding + # List U8, fmt -[[custom(22)]]-> { rest : List U8, result : [Err [TooShort], Ok ( val, val1 )a] } where fmt implements DecoderFormatting, val implements Decoding, val1 implements Decoding # Specialization lambda sets: # @<1>: [[custom(22)]] #Derived.decoder_(arity:2) = diff --git a/crates/compiler/test_derive/src/encoding.rs b/crates/compiler/test_derive/src/encoding.rs index 481ab8ff7a3..82740620599 100644 --- a/crates/compiler/test_derive/src/encoding.rs +++ b/crates/compiler/test_derive/src/encoding.rs @@ -188,8 +188,8 @@ fn empty_record() { derive_test(ToEncoder, v!(EMPTY_RECORD), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # {} -[[toEncoder_{}(0)]]-> Encoder fmt | fmt implements EncoderFormatting - # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) | fmt implements EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> Encoder fmt where fmt implements EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) where fmt implements EncoderFormatting # Specialization lambda sets: # @<1>: [[toEncoder_{}(0)]] # @<2>: [[custom(2) {}]] @@ -208,8 +208,8 @@ fn zero_field_record() { derive_test(ToEncoder, v!({}), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # {} -[[toEncoder_{}(0)]]-> Encoder fmt | fmt implements EncoderFormatting - # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) | fmt implements EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> Encoder fmt where fmt implements EncoderFormatting + # {} -[[toEncoder_{}(0)]]-> (List U8, fmt -[[custom(2) {}]]-> List U8) where fmt implements EncoderFormatting # Specialization lambda sets: # @<1>: [[toEncoder_{}(0)]] # @<2>: [[custom(2) {}]] @@ -228,11 +228,11 @@ fn one_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8 } - # { a : val } -[[toEncoder_{a}(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding - # { a : val } -[[toEncoder_{a}(0)]]-> (List U8, fmt -[[custom(2) { a : val }]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding + # { a : val } -[[toEncoder_{a}(0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding + # { a : val } -[[toEncoder_{a}(0)]]-> (List U8, fmt -[[custom(2) { a : val }]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a}(0)]] - # @<2>: [[custom(2) { a : val }]] | val implements Encoding + # @<2>: [[custom(2) { a : val }]] where val implements Encoding #Derived.toEncoder_{a} = \#Derived.rcd -> custom @@ -251,11 +251,11 @@ fn two_field_record() { derive_test(ToEncoder, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding - # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # { a : val, b : val1 } -[[toEncoder_{a,b}(0)]]-> (List U8, fmt -[[custom(2) { a : val, b : val1 }]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_{a,b}(0)]] - # @<2>: [[custom(2) { a : val, b : val1 }]] | val implements Encoding, val1 implements Encoding + # @<2>: [[custom(2) { a : val, b : val1 }]] where val implements Encoding, val1 implements Encoding #Derived.toEncoder_{a,b} = \#Derived.rcd -> custom @@ -278,11 +278,11 @@ fn two_field_tuple() { derive_test(ToEncoder, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding - # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # ( val, val1 )* -[[toEncoder_(arity:2)(0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # ( val, val1 )a -[[toEncoder_(arity:2)(0)]]-> (List U8, fmt -[[custom(2) ( val, val1 )a]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_(arity:2)(0)]] - # @<2>: [[custom(2) ( val, val1 )*]] | val implements Encoding, val1 implements Encoding + # @<2>: [[custom(2) ( val, val1 )*]] where val implements Encoding, val1 implements Encoding #Derived.toEncoder_(arity:2) = \#Derived.tup -> custom @@ -314,8 +314,8 @@ fn tag_one_label_zero_args() { derive_test(ToEncoder, v!([A]), |golden| { assert_snapshot!(golden, @r###" # derived for [A] - # [A] -[[toEncoder_[A 0](0)]]-> Encoder fmt | fmt implements EncoderFormatting - # [A] -[[toEncoder_[A 0](0)]]-> (List U8, fmt -[[custom(2) [A]]]-> List U8) | fmt implements EncoderFormatting + # [A] -[[toEncoder_[A 0](0)]]-> Encoder fmt where fmt implements EncoderFormatting + # [A] -[[toEncoder_[A 0](0)]]-> (List U8, fmt -[[custom(2) [A]]]-> List U8) where fmt implements EncoderFormatting # Specialization lambda sets: # @<1>: [[toEncoder_[A 0](0)]] # @<2>: [[custom(2) [A]]] @@ -338,11 +338,11 @@ fn tag_one_label_two_args() { derive_test(ToEncoder, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding - # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [A val val1] -[[toEncoder_[A 2](0)]]-> (List U8, fmt -[[custom(4) [A val val1]]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 2](0)]] - # @<2>: [[custom(4) [A val val1]]] | val implements Encoding, val1 implements Encoding + # @<2>: [[custom(4) [A val val1]]] where val implements Encoding, val1 implements Encoding #Derived.toEncoder_[A 2] = \#Derived.tag -> custom @@ -366,11 +366,11 @@ fn tag_two_labels() { |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding - # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [A val val1 val1, B val1] -[[toEncoder_[A 3,B 1](0)]]-> (List U8, fmt -[[custom(6) [A val val1 val1, B val1]]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[A 3,B 1](0)]] - # @<2>: [[custom(6) [A val val1 val1, B val1]]] | val implements Encoding, val1 implements Encoding + # @<2>: [[custom(6) [A val val1 val1, B val1]]] where val implements Encoding, val1 implements Encoding #Derived.toEncoder_[A 3,B 1] = \#Derived.tag -> custom @@ -402,11 +402,11 @@ fn recursive_tag_union() { |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding - # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding + # [Cons val val1, Nil] -[[toEncoder_[Cons 2,Nil 0](0)]]-> (List U8, fmt -[[custom(4) [Cons val val1, Nil]]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding, val1 implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_[Cons 2,Nil 0](0)]] - # @<2>: [[custom(4) [Cons val val1, Nil]]] | val implements Encoding, val1 implements Encoding + # @<2>: [[custom(4) [Cons val val1, Nil]]] where val implements Encoding, val1 implements Encoding #Derived.toEncoder_[Cons 2,Nil 0] = \#Derived.tag -> custom @@ -429,11 +429,11 @@ fn list() { derive_test(ToEncoder, v!(Symbol::LIST_LIST v!(STR)), |golden| { assert_snapshot!(golden, @r###" # derived for List Str - # List val -[[toEncoder_list(0)]]-> Encoder fmt | fmt implements EncoderFormatting, val implements Encoding - # List val -[[toEncoder_list(0)]]-> (List U8, fmt -[[custom(4) (List val)]]-> List U8) | fmt implements EncoderFormatting, val implements Encoding + # List val -[[toEncoder_list(0)]]-> Encoder fmt where fmt implements EncoderFormatting, val implements Encoding + # List val -[[toEncoder_list(0)]]-> (List U8, fmt -[[custom(4) (List val)]]-> List U8) where fmt implements EncoderFormatting, val implements Encoding # Specialization lambda sets: # @<1>: [[toEncoder_list(0)]] - # @<2>: [[custom(4) (List val)]] | val implements Encoding + # @<2>: [[custom(4) (List val)]] where val implements Encoding #Derived.toEncoder_list = \#Derived.lst -> custom diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index 1d645d5d8a4..96a119199e4 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -151,8 +151,8 @@ fn empty_record() { derive_test(Hash, v!(EMPTY_RECORD), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher where hasher implements Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher where hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{}(0)]] #Derived.hash_{} = \#Derived.hasher, #Derived.rcd -> #Derived.hasher @@ -166,8 +166,8 @@ fn zero_field_record() { derive_test(Hash, v!({}), |golden| { assert_snapshot!(golden, @r###" # derived for {} - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher - # hasher, {} -[[hash_{}(0)]]-> hasher | hasher implements Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher where hasher implements Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher where hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{}(0)]] #Derived.hash_{} = \#Derived.hasher, #Derived.rcd -> #Derived.hasher @@ -181,8 +181,8 @@ fn one_field_record() { derive_test(Hash, v!({ a: v!(U8), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8 } - # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a implements Hash, hasher implements Hasher - # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a implements Hash, hasher implements Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher where a implements Hash, hasher implements Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher where a implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a}(0)]] #Derived.hash_{a} = @@ -197,8 +197,8 @@ fn two_field_record() { derive_test(Hash, v!({ a: v!(U8), b: v!(STR), }), |golden| { assert_snapshot!(golden, @r###" # derived for { a : U8, b : Str } - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher - # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher where a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher where a implements Hash, a1 implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_{a,b}(0)]] #Derived.hash_{a,b} = @@ -214,8 +214,8 @@ fn two_element_tuple() { derive_test(Hash, v!((v!(U8), v!(STR),)), |golden| { assert_snapshot!(golden, @r###" # derived for ( U8, Str )* - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher - # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher where a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, ( a, a1 )* -[[hash_(arity:2)(0)]]-> hasher where a implements Hash, a1 implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_(arity:2)(0)]] #Derived.hash_(arity:2) = @@ -231,8 +231,8 @@ fn tag_one_label_no_payloads() { derive_test(Hash, v!([A]), |golden| { assert_snapshot!(golden, @r###" # derived for [A] - # hasher, [A] -[[hash_[A 0](0)]]-> hasher | hasher implements Hasher - # hasher, [A] -[[hash_[A 0](0)]]-> hasher | hasher implements Hasher + # hasher, [A] -[[hash_[A 0](0)]]-> hasher where hasher implements Hasher + # hasher, [A] -[[hash_[A 0](0)]]-> hasher where hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 0](0)]] #Derived.hash_[A 0] = \#Derived.hasher, A -> #Derived.hasher @@ -246,8 +246,8 @@ fn tag_one_label_newtype() { derive_test(Hash, v!([A v!(U8) v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str] - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher - # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher | a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher where a implements Hash, a1 implements Hash, hasher implements Hasher + # hasher, [A a a1] -[[hash_[A 2](0)]]-> hasher where a implements Hash, a1 implements Hash, hasher implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 2](0)]] #Derived.hash_[A 2] = @@ -263,8 +263,8 @@ fn tag_two_labels() { derive_test(Hash, v!([A v!(U8) v!(STR) v!(U16), B v!(STR)]), |golden| { assert_snapshot!(golden, @r###" # derived for [A U8 Str U16, B Str] - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash, a3 implements Hash - # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a where a implements Hasher, a1 implements Hash, a2 implements Hash, a3 implements Hash + # a, [A a1 a2 a3, B a3] -[[hash_[A 3,B 1](0)]]-> a where a implements Hasher, a1 implements Hash, a2 implements Hash, a3 implements Hash # Specialization lambda sets: # @<1>: [[hash_[A 3,B 1](0)]] #Derived.hash_[A 3,B 1] = @@ -285,8 +285,8 @@ fn tag_two_labels_no_payloads() { derive_test(Hash, v!([A, B]), |golden| { assert_snapshot!(golden, @r###" # derived for [A, B] - # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a | a implements Hasher - # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a | a implements Hasher + # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a where a implements Hasher + # a, [A, B] -[[hash_[A 0,B 0](0)]]-> a where a implements Hasher # Specialization lambda sets: # @<1>: [[hash_[A 0,B 0](0)]] #Derived.hash_[A 0,B 0] = @@ -304,8 +304,8 @@ fn recursive_tag_union() { derive_test(Hash, v!([Nil, Cons v!(U8) v!(^lst) ] as lst), |golden| { assert_snapshot!(golden, @r###" # derived for [Cons U8 $rec, Nil] as $rec - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash - # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a | a implements Hasher, a1 implements Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a where a implements Hasher, a1 implements Hash, a2 implements Hash + # a, [Cons a1 a2, Nil] -[[hash_[Cons 2,Nil 0](0)]]-> a where a implements Hasher, a1 implements Hash, a2 implements Hash # Specialization lambda sets: # @<1>: [[hash_[Cons 2,Nil 0](0)]] #Derived.hash_[Cons 2,Nil 0] = diff --git a/crates/compiler/test_gen/src/gen_abilities.rs b/crates/compiler/test_gen/src/gen_abilities.rs index a154da57ce9..222f426365a 100644 --- a/crates/compiler/test_gen/src/gen_abilities.rs +++ b/crates/compiler/test_gen/src/gen_abilities.rs @@ -21,7 +21,7 @@ fn hash_specialization() { app "test" provides [main] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] @@ -44,7 +44,7 @@ fn hash_specialization_multiple_add() { app "test" provides [main] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [ MHash {hash: hashId} ] @@ -71,7 +71,7 @@ fn alias_member_specialization() { app "test" provides [main] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] @@ -96,9 +96,9 @@ fn ability_constrained_in_non_member_usage() { app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash - mulMHashes : a, a -> U64 | a implements MHash + mulMHashes : a, a -> U64 where a implements MHash mulMHashes = \x, y -> hash x * hash y Id := U64 implements [MHash {hash}] @@ -121,7 +121,7 @@ fn ability_constrained_in_non_member_usage_inferred() { app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash mulMHashes = \x, y -> hash x * hash y @@ -145,9 +145,9 @@ fn ability_constrained_in_non_member_multiple_specializations() { app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash - mulMHashes : a, b -> U64 | a implements MHash, b implements MHash + mulMHashes : a, b -> U64 where a implements MHash, b implements MHash mulMHashes = \x, y -> hash x * hash y Id := U64 implements [MHash { hash: hashId }] @@ -173,7 +173,7 @@ fn ability_constrained_in_non_member_multiple_specializations_inferred() { app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash mulMHashes = \x, y -> hash x * hash y @@ -200,7 +200,7 @@ fn ability_used_as_type_still_compiles() { app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash mulMHashes : MHash, MHash -> U64 mulMHashes = \x, y -> hash x * hash y @@ -227,15 +227,15 @@ fn bounds_to_multiple_abilities() { r#" app "test" provides [main] to "./platform" - Idempot implements idempot : a -> a | a implements Idempot - Consume implements consume : a -> Str | a implements Consume + Idempot implements idempot : a -> a where a implements Idempot + Consume implements consume : a -> Str where a implements Consume Hello := Str implements [Idempot { idempot: idempotHello }, Consume { consume: consumeHello }] idempotHello = \@Hello msg -> @Hello msg consumeHello = \@Hello msg -> msg - lifecycle : a -> Str | a implements Idempot & Consume + lifecycle : a -> Str where a implements Idempot & Consume lifecycle = \x -> idempot x |> consume main = lifecycle (@Hello "hello world") @@ -254,18 +254,18 @@ fn encode() { r#" app "test" provides [myU8Bytes] to "./platform" - MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format + MEncoder fmt := List U8, fmt -> List U8 where fmt implements Format MEncoding implements - toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format + toEncoder : val -> MEncoder fmt where val implements MEncoding, fmt implements Format Format implements - u8 : U8 -> MEncoder fmt | fmt implements Format + u8 : U8 -> MEncoder fmt where fmt implements Format - appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt implements Format + appendWith : List U8, MEncoder fmt, fmt -> List U8 where fmt implements Format appendWith = \lst, (@MEncoder doFormat), fmt -> doFormat lst fmt - toBytes : val, fmt -> List U8 | val implements MEncoding, fmt implements Format + toBytes : val, fmt -> List U8 where val implements MEncoding, fmt implements Format toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt @@ -301,19 +301,19 @@ fn decode() { MDecodeError : [TooShort, Leftover (List U8)] - MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting + MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } where fmt implements MDecoderFormatting MDecoding implements - decoder : MDecoder val fmt | val implements MDecoding, fmt implements MDecoderFormatting + decoder : MDecoder val fmt where val implements MDecoding, fmt implements MDecoderFormatting MDecoderFormatting implements - u8 : MDecoder U8 fmt | fmt implements MDecoderFormatting + u8 : MDecoder U8 fmt where fmt implements MDecoderFormatting - decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting + decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } where fmt implements MDecoderFormatting decodeWith = \lst, (@MDecoder doDecode), fmt -> doDecode lst fmt fromBytes : List U8, fmt -> Result val MDecodeError - | fmt implements MDecoderFormatting, val implements MDecoding + where fmt implements MDecoderFormatting, val implements MDecoding fromBytes = \lst, fmt -> when decodeWith lst decoder fmt is { result, rest } -> diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index 2e0d767237b..c9b84c7bc8c 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -960,7 +960,7 @@ fn list_walk_implements_position() { r#" Option a : [Some a, None] - find : List a, a -> Option Nat | a implements Eq + find : List a, a -> Option Nat where a implements Eq find = \list, needle -> findHelp list needle |> .v @@ -3693,7 +3693,7 @@ fn list_walk_backwards_implements_position() { r#" Option a : [Some a, None] - find : List a, a -> Option Nat | a implements Eq + find : List a, a -> Option Nat where a implements Eq find = \list, needle -> findHelp list needle |> .v diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs index 68df70a7676..010657f9d55 100644 --- a/crates/compiler/test_gen/src/gen_num.rs +++ b/crates/compiler/test_gen/src/gen_num.rs @@ -891,7 +891,7 @@ fn gen_wrap_int_neq() { assert_evals_to!( indoc!( r#" - wrappedNotEq : a, a -> Bool | a implements Eq + wrappedNotEq : a, a -> Bool where a implements Eq wrappedNotEq = \num1, num2 -> num1 != num2 diff --git a/crates/compiler/test_mono/src/tests.rs b/crates/compiler/test_mono/src/tests.rs index 9632c7b4f2d..18ae06ded4e 100644 --- a/crates/compiler/test_mono/src/tests.rs +++ b/crates/compiler/test_mono/src/tests.rs @@ -1345,7 +1345,7 @@ fn specialize_ability_call() { app "test" provides [main] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] @@ -1380,13 +1380,13 @@ fn encode() { r#" app "test" provides [myU8Bytes] to "./platform" - MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format + MEncoder fmt := List U8, fmt -> List U8 where fmt implements Format MEncoding implements - toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format + toEncoder : val -> MEncoder fmt where val implements MEncoding, fmt implements Format Format implements - u8 : U8 -> MEncoder fmt | fmt implements Format + u8 : U8 -> MEncoder fmt where fmt implements Format Linear := {} implements [Format {u8}] @@ -2603,15 +2603,15 @@ fn unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unifica r#" app "test" provides [main] to "./platform" - MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format + MEncoder fmt := List U8, fmt -> List U8 where fmt implements Format MEncoding implements - toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format + toEncoder : val -> MEncoder fmt where val implements MEncoding, fmt implements Format Format implements - u8 : {} -> MEncoder fmt | fmt implements Format - str : {} -> MEncoder fmt | fmt implements Format - tag : MEncoder fmt -> MEncoder fmt | fmt implements Format + u8 : {} -> MEncoder fmt where fmt implements Format + str : {} -> MEncoder fmt where fmt implements Format + tag : MEncoder fmt -> MEncoder fmt where fmt implements Format Linear := {} implements [Format {u8: lU8, str: lStr, tag: lTag}] diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc index 3b411cb332c..1ae763fa665 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.roc @@ -1,4 +1,4 @@ MEq implements - eq b c : a, a -> U64 | a implements MEq + eq b c : a, a -> U64 where a implements MEq 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc index 8d0aa047c93..d4b478df183 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.roc @@ -1,5 +1,5 @@ MEq implements - eq : a, a -> U64 | a implements MEq - neq : a, a -> U64 | a implements MEq + eq : a, a -> U64 where a implements MEq + neq : a, a -> U64 where a implements MEq 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc b/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc index 92086a5f159..fb55dc82199 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.roc @@ -1,4 +1,4 @@ MEq implements -eq : a, a -> U64 | a implements MEq +eq : a, a -> U64 where a implements MEq 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc index 798560ef410..85870f77c63 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.roc @@ -1,3 +1,3 @@ -Hash implements hash : a -> U64 | a implements Hash +Hash implements hash : a -> U64 where a implements Hash 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc index 1c5fad72e51..4f6f9c75e07 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.roc @@ -1,5 +1,5 @@ -Ab1 implements ab1 : a -> {} | a implements Ab1 +Ab1 implements ab1 : a -> {} where a implements Ab1 -Ab2 implements ab2 : a -> {} | a implements Ab2 +Ab2 implements ab2 : a -> {} where a implements Ab2 1 diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc index 32173c522a0..e399dd7e0d2 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc @@ -1,9 +1,9 @@ A := U8 implements [Eq, Hash] -A := a | a implements Other +A := a where a implements Other implements [Eq, Hash] -A := a | a implements Other +A := a where a implements Other implements [Eq, Hash] A := U8 implements [Eq { eq }, Hash { hash }] @@ -16,7 +16,7 @@ A := U8 implements [Hash, Eq { eq, eq1 }] A := U8 implements [] -A := a | a implements Other +A := a where a implements Other implements [Eq { eq }, Hash { hash }] A := U8 implements [Eq {}] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc index 3228574abca..0a329cbbdcc 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.roc @@ -1,8 +1,8 @@ A := U8 implements [Eq, Hash] -A := a | a implements Other implements [Eq, Hash] +A := a where a implements Other implements [Eq, Hash] -A := a | a implements Other +A := a where a implements Other implements [Eq, Hash] A := U8 implements [Eq {eq}, Hash {hash}] @@ -15,7 +15,7 @@ A := U8 implements [Hash, Eq {eq, eq1}] A := U8 implements [] -A := a | a implements Other +A := a where a implements Other implements [Eq {eq}, Hash {hash}] A := U8 implements [Eq {}] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc index 6b11f13621c..8406a9d704e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a implements A +f : a -> (b -> c) where a implements A f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc index 70a5869e419..15ab48af353 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.formatted.roc @@ -1,5 +1,5 @@ -f : a -> b | a implements Hash & Eq, b implements Eq & Hash & Display +f : a -> b where a implements Hash & Eq, b implements Eq & Hash & Display -f : a -> b | a implements Hash & Eq, b implements Hash & Display & Eq +f : a -> b where a implements Hash & Eq, b implements Hash & Display & Eq f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc index 2a151bfd52b..c77b4c76e5f 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.roc @@ -1,7 +1,7 @@ -f : a -> b | a implements Hash & Eq, b implements Eq & Hash & Display +f : a -> b where a implements Hash & Eq, b implements Eq & Hash & Display f : a -> b - | a implements Hash & Eq, + where a implements Hash & Eq, b implements Hash & Display & Eq f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc index 4de00586ac5..8122c5e15b0 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a implements A, b implements Eq, c implements Ord +f : a -> (b -> c) where a implements A, b implements Eq, c implements Ord f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc index 0ebb9de5a06..d5d6c87616e 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) | a implements Hash, b has Eq, c implements Ord +f : a -> (b -> c) where a implements Hash, b has Eq, c implements Ord f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc index 98fd1445413..8a999d8baa5 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.roc @@ -1,5 +1,5 @@ f : a -> (b -> c) - | a implements Hash, + where a implements Hash, b implements Eq, c implements Ord diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc index d60270f465b..6fdaa51b786 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.roc @@ -1,3 +1,3 @@ -f : a | a implements A +f : a where a implements A f diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc index bdef6cc7def..1b14b8c6b40 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.formatted.roc @@ -1,3 +1,3 @@ -f : a -> U64 | a implements Hash +f : a -> U64 where a implements Hash f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc index 050ad469105..c1478690782 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.roc @@ -1,4 +1,4 @@ f : a -> U64 - | a implements Hash + where a implements Hash f diff --git a/crates/compiler/test_syntax/tests/test_fmt.rs b/crates/compiler/test_syntax/tests/test_fmt.rs index 4725aac92c2..7a0feeb82c2 100644 --- a/crates/compiler/test_syntax/tests/test_fmt.rs +++ b/crates/compiler/test_syntax/tests/test_fmt.rs @@ -5457,14 +5457,14 @@ mod test_fmt { expr_formats_to( indoc!( r#" - A := a | a implements Hash implements [ Eq, Hash ] + A := a where a implements Hash implements [ Eq, Hash ] 0 "# ), indoc!( r#" - A := a | a implements Hash + A := a where a implements Hash implements [Eq, Hash] 0 @@ -5568,7 +5568,7 @@ mod test_fmt { expr_formats_same(indoc!( r#" - A := a | a implements Other + A := a where a implements Other implements [Eq { eq }, Hash { hash }] 0 @@ -5625,7 +5625,7 @@ mod test_fmt { dataIndices : List Nat, data : List (T k v), size : Nat, - } | k implements Hash & Eq + } where k implements Hash & Eq a "# @@ -5839,10 +5839,10 @@ mod test_fmt { A implements ## This is member ab - ab : a -> a | a implements A + ab : a -> a where a implements A ## This is member de - de : a -> a | a implements A + de : a -> a where a implements A f = g "# @@ -5884,7 +5884,7 @@ mod test_fmt { fn clauses_with_multiple_abilities() { expr_formats_same(indoc!( r#" - f : {} -> a | a implements Eq & Hash & Decode + f : {} -> a where a implements Eq & Hash & Decode f "# @@ -5893,7 +5893,7 @@ mod test_fmt { expr_formats_to( indoc!( r#" - f : {} -> a | a implements Eq & Hash & Decode, + f : {} -> a where a implements Eq & Hash & Decode, b implements Eq & Hash f @@ -5902,10 +5902,10 @@ mod test_fmt { indoc!( // TODO: ideally, this would look a bit nicer - consider // f : {} -> a - // | a implements Eq & Hash & Decode, + // where a implements Eq & Hash & Decode, // b implements Eq & Hash r#" - f : {} -> a | a implements Eq & Hash & Decode, b implements Eq & Hash + f : {} -> a where a implements Eq & Hash & Decode, b implements Eq & Hash f "# diff --git a/crates/compiler/types/src/pretty_print.rs b/crates/compiler/types/src/pretty_print.rs index b132a0199e4..6e8463aeb5d 100644 --- a/crates/compiler/types/src/pretty_print.rs +++ b/crates/compiler/types/src/pretty_print.rs @@ -602,7 +602,13 @@ fn variable_to_string( ctx.able_variables.sort(); ctx.able_variables.dedup(); for (i, (var, abilities)) in ctx.able_variables.into_iter().enumerate() { - buf.push_str(if i == 0 { " | " } else { ", " }); + if i == 0 { + buf.push(' '); + buf.push_str(roc_parse::keyword::WHERE) + } else { + buf.push(','); + } + buf.push(' '); buf.push_str(var); buf.push(' '); buf.push_str(roc_parse::keyword::IMPLEMENTS); diff --git a/crates/compiler/types/src/types.rs b/crates/compiler/types/src/types.rs index efd49d2088f..13a92447bbe 100644 --- a/crates/compiler/types/src/types.rs +++ b/crates/compiler/types/src/types.rs @@ -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 implements Default +/// Default has default : {} -> a where 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 diff --git a/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt b/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt index 6cc44c9d8b9..894ded1fa3a 100644 --- a/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt +++ b/crates/compiler/uitest/tests/ability/bounds/expand_able_variables_in_type_alias.txt @@ -1,7 +1,7 @@ # +opt infer:print_only_under_alias app "test" provides [main] to "./platform" -F a : a | a implements Hash +F a : a where a implements Hash main : F a -> F a -#^^^^{-1} a -[[main(0)]]-> a | a implements Hash +#^^^^{-1} a -[[main(0)]]-> a where a implements Hash diff --git a/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt b/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt index 4d18952a60e..32f23d7db0e 100644 --- a/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt +++ b/crates/compiler/uitest/tests/ability/bounds/multiple_variables_bound_to_an_ability_from_type_def.txt @@ -1,7 +1,7 @@ # +opt infer:print_only_under_alias app "test" provides [main] to "./platform" -F a : a | a implements Hash & Eq & Decoding +F a : a where a implements Hash & Eq & Decoding main : F a -> F a -#^^^^{-1} a -[[main(0)]]-> a | a implements Hash & Decoding & Eq +#^^^^{-1} a -[[main(0)]]-> a where a implements Hash & Decoding & Eq diff --git a/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt b/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt index a06679108d5..490c2655120 100644 --- a/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt +++ b/crates/compiler/uitest/tests/ability/bounds/rigid_able_bounds_are_superset_of_flex_bounds_admitted.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" -f : x -> x | x implements Hash -g : x -> x | x implements Decoding & Encoding +f : x -> x where x implements Hash +g : x -> x where x implements Decoding & Encoding -main : x -> x | x implements Hash & Decoding & Encoding +main : x -> x where x implements Hash & Decoding & Encoding main = \x -> x |> f |> g -#^^^^{-1} x -[[main(0)]]-> x | x implements Hash & Encoding & Decoding +#^^^^{-1} x -[[main(0)]]-> x where x implements Hash & Encoding & Decoding diff --git a/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt b/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt index 3868cf4d177..4bb2874aa7c 100644 --- a/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt +++ b/crates/compiler/uitest/tests/ability/generalize_inferred_opaque_variable_bound_to_ability_issue_4408.txt @@ -1,6 +1,6 @@ app "test" provides [top] to "./platform" -MDict u := (List u) | u implements Hash & Eq +MDict u := (List u) where u implements Hash & Eq bot : MDict k -> MDict k bot = \@MDict data -> @@ -9,4 +9,4 @@ bot = \@MDict data -> top : MDict v -> MDict v top = \x -> bot x -#^^^{-1} MDict v -[[top(0)]]-> MDict v | v implements Hash & Eq +#^^^{-1} MDict v -[[top(0)]]-> MDict v where v implements Hash & Eq diff --git a/crates/compiler/uitest/tests/ability/smoke/decoder.txt b/crates/compiler/uitest/tests/ability/smoke/decoder.txt index 77546828dd9..1ceffa6ecc3 100644 --- a/crates/compiler/uitest/tests/ability/smoke/decoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/decoder.txt @@ -2,19 +2,19 @@ app "test" provides [myU8] to "./platform" MDecodeError : [TooShort, Leftover (List U8)] -MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting +MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } where fmt implements MDecoderFormatting MDecoding has - decoder : MDecoder val fmt | val implements MDecoding, fmt implements MDecoderFormatting + decoder : MDecoder val fmt where val implements MDecoding, fmt implements MDecoderFormatting MDecoderFormatting has - u8 : MDecoder U8 fmt | fmt implements MDecoderFormatting + u8 : MDecoder U8 fmt where fmt implements MDecoderFormatting -decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } | fmt implements MDecoderFormatting +decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } where fmt implements MDecoderFormatting decodeWith = \lst, (@MDecoder doDecode), fmt -> doDecode lst fmt fromBytes : List U8, fmt -> Result val MDecodeError - | fmt implements MDecoderFormatting, val implements MDecoding + where fmt implements MDecoderFormatting, val implements MDecoding fromBytes = \lst, fmt -> when decodeWith lst decoder fmt is { result, rest } -> @@ -34,7 +34,7 @@ u8 = @MDecoder \lst, @Linear {} -> MyU8 := U8 implements [MDecoding {decoder}] decoder = @MDecoder \lst, fmt -> -#^^^^^^^{-1} MyU8#decoder(12): MDecoder MyU8 fmt | fmt implements MDecoderFormatting +#^^^^^^^{-1} MyU8#decoder(12): MDecoder MyU8 fmt where fmt implements MDecoderFormatting when decodeWith lst u8 fmt is { result, rest } -> { result: Result.map result (\n -> @MyU8 n), rest } diff --git a/crates/compiler/uitest/tests/ability/smoke/encoder.txt b/crates/compiler/uitest/tests/ability/smoke/encoder.txt index f22517fb13f..88dee647b49 100644 --- a/crates/compiler/uitest/tests/ability/smoke/encoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/encoder.txt @@ -1,17 +1,17 @@ app "test" provides [myU8Bytes] to "./platform" -MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format +MEncoder fmt := List U8, fmt -> List U8 where fmt implements Format MEncoding has - toEncoder : val -> MEncoder fmt | val implements MEncoding, fmt implements Format + toEncoder : val -> MEncoder fmt where val implements MEncoding, fmt implements Format Format has - u8 : U8 -> MEncoder fmt | fmt implements Format + u8 : U8 -> MEncoder fmt where fmt implements Format -appendWith : List U8, MEncoder fmt, fmt -> List U8 | fmt implements Format +appendWith : List U8, MEncoder fmt, fmt -> List U8 where fmt implements Format appendWith = \lst, (@MEncoder doFormat), fmt -> doFormat lst fmt -toBytes : val, fmt -> List U8 | val implements MEncoding, fmt implements Format +toBytes : val, fmt -> List U8 where val implements MEncoding, fmt implements Format toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt @@ -23,7 +23,7 @@ u8 = \n -> @MEncoder (\lst, @Linear {} -> List.append lst n) MyU8 := U8 implements [MEncoding {toEncoder}] toEncoder = \@MyU8 n -> u8 n -#^^^^^^^^^{-1} MyU8#toEncoder(11): MyU8 -[[toEncoder(11)]]-> MEncoder fmt | fmt implements Format +#^^^^^^^^^{-1} MyU8#toEncoder(11): MyU8 -[[toEncoder(11)]]-> MEncoder fmt where fmt implements Format myU8Bytes = toBytes (@MyU8 15) (@Linear {}) #^^^^^^^^^{-1} List U8 diff --git a/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt b/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt index 020da7aefc8..0d66b5f47a6 100644 --- a/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt +++ b/crates/compiler/uitest/tests/ability/specialize/bool_decoder.txt @@ -3,4 +3,4 @@ app "test" provides [main] to "./platform" main : Decoder Bool _ main = Decode.custom \bytes, fmt -> Decode.decodeWith bytes Decode.decoder fmt - # ^^^^^^^^^^^^^^ Decoding#Decode.decoder(4): Decoder Bool fmt | fmt implements DecoderFormatting + # ^^^^^^^^^^^^^^ Decoding#Decode.decoder(4): Decoder Bool fmt where fmt implements DecoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt b/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt index fa6c3cccc02..00a42f8a7e6 100644 --- a/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt +++ b/crates/compiler/uitest/tests/ability/specialize/bool_hash.txt @@ -2,4 +2,4 @@ app "test" provides [main] to "./platform" main = \h -> Hash.hash h Bool.true - # ^^^^^^^^^ Hash#Hash.hash(1): a, Bool -[[Hash.hashBool(9)]]-> a | a implements Hasher + # ^^^^^^^^^ Hash#Hash.hash(1): a, Bool -[[Hash.hashBool(9)]]-> a where a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt b/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt index e2c68883730..72fd873b894 100644 --- a/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt +++ b/crates/compiler/uitest/tests/ability/specialize/bool_to_encoder.txt @@ -1,4 +1,4 @@ app "test" provides [main] to "./platform" main = Encode.toEncoder Bool.true -# ^^^^^^^^^^^^^^^^ Encoding#Encode.toEncoder(2): Bool -[[] + fmt:Encode.bool(17):1]-> Encoder fmt | fmt implements EncoderFormatting +# ^^^^^^^^^^^^^^^^ Encoding#Encode.toEncoder(2): Bool -[[] + fmt:Encode.bool(17):1]-> Encoder fmt where fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt index 13105803adb..9ea64135f15 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_decoder_derive.txt @@ -6,4 +6,4 @@ N := U8 implements [Decoding] main : Decoder N _ main = Decode.custom \bytes, fmt -> Decode.decodeWith bytes Decode.decoder fmt -# ^^^^^^^^^^^^^^ N#Decode.decoder(3): List U8, fmt -[[7]]-> { rest : List U8, result : [Err [TooShort], Ok U8] } | fmt implements DecoderFormatting +# ^^^^^^^^^^^^^^ N#Decode.decoder(3): List U8, fmt -[[7]]-> { rest : List U8, result : [Err [TooShort], Ok U8] } where fmt implements DecoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt index 71decfe1295..6e1b247dc6b 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_encoder_derive.txt @@ -3,4 +3,4 @@ app "test" provides [main] to "./platform" N := U8 implements [Encoding] main = Encode.toEncoder (@N 15) -# ^^^^^^^^^^^^^^^^ N#Encode.toEncoder(3): N -[[#N_toEncoder(3)]]-> Encoder fmt | fmt implements EncoderFormatting +# ^^^^^^^^^^^^^^^^ N#Encode.toEncoder(3): N -[[#N_toEncoder(3)]]-> Encoder fmt where fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt index 957352040cc..a1260a48fd1 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_custom.txt @@ -5,4 +5,4 @@ Noop := {} implements [Hash {hash}] hash = \hasher, @Noop {} -> hasher main = \hasher -> hash hasher (@Noop {}) -#^^^^{-1} hasher -[[main(0)]]-> hasher | hasher implements Hasher +#^^^^{-1} hasher -[[main(0)]]-> hasher where hasher implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt index b9aabd1cc55..bf0f35a6072 100644 --- a/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt +++ b/crates/compiler/uitest/tests/ability/specialize/opaque_hash_derive.txt @@ -3,4 +3,4 @@ app "test" provides [main] to "./platform" N := U8 implements [Hash] main = \hasher, @N n -> Hash.hash hasher (@N n) -# ^^^^^^^^^ N#Hash.hash(3): a, N -[[#N_hash(3)]]-> a | a implements Hasher +# ^^^^^^^^^ N#Hash.hash(3): a, N -[[#N_hash(3)]]-> a where a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt index 333219f2a80..09856a4f4c3 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt @@ -1,11 +1,11 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a implements F, b implements G -G has g : b -> {} | b implements G +F has f : a -> (b -> {}) where a implements F, b implements G +G has g : b -> {} where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) where b implements G Go := {} implements [G {g}] g = \@Go {} -> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt index ed7cc865d3a..7cf1ab95b89 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt @@ -1,11 +1,11 @@ app "test" provides [main] to "./platform" -F has f : a -> ({} -> b) | a implements F, b implements G -G has g : {} -> b | b implements G +F has f : a -> ({} -> b) where a implements F, b implements G +G has g : {} -> b where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> ({} -[[] + b:g(4):1]-> b) | b implements G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> ({} -[[] + b:g(4):1]-> b) where b implements G Go := {} implements [G {g}] g = \{} -> @Go {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt index 951c75103cd..fd4340d36ab 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt @@ -1,7 +1,7 @@ app "test" provides [f] to "./platform" -J has j : j -> (k -> {}) | j implements J, k implements K -K has k : k -> {} | k implements K +J has j : j -> (k -> {}) where j implements J, k implements K +K has k : k -> {} where k implements K C := {} implements [J {j: jC}] jC = \@C _ -> k @@ -18,5 +18,5 @@ f = \flag, a, c -> A -> j a B -> j a it c -# ^ k | k implements K -# ^^ k -[[] + j:j(2):2]-> {} | j implements J, k implements K +# ^ k where k implements K +# ^^ k -[[] + j:j(2):2]-> {} where j implements J, k implements K diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt index 323d607f776..907ffcb1e14 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt @@ -1,32 +1,32 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) | j implements J, k implements K -K has k : k -> {} | k implements K +J has j : j -> (k -> {}) where j implements J, k implements K +K has k : k -> {} where k implements K C := {} implements [J {j: jC}] jC = \@C _ -> k -#^^{-1} C -[[jC(8)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K +#^^{-1} C -[[jC(8)]]-> (k -[[] + k:k(4):1]-> {}) where k implements K D := {} implements [J {j: jD}] jD = \@D _ -> k -#^^{-1} D -[[jD(9)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K +#^^{-1} D -[[jD(9)]]-> (k -[[] + k:k(4):1]-> {}) where k implements K E := {} implements [K {k}] k = \@E _ -> {} #^{-1} E#k(10): E -[[k(10)]]-> {} f = \flag, a, b -> -# ^ j | j implements J -# ^ j | j implements J +# ^ j where j implements J +# ^ j where j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) where j implements J, j1 has J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) where j implements J, j1 has J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K main = (f A (@C {}) (@D {})) (@E {}) # ^ [A, B], C, D -[[f(11)]]-> (E -[[k(10)]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt index a6f436e4b11..27f1f4b11dd 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt @@ -1,15 +1,15 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) | j implements J, k implements K -K has k : k -> {} | k implements K +J has j : j -> (k -> {}) where j implements J, k implements K +K has k : k -> {} where k implements K C := {} implements [J {j: jC}] jC = \@C _ -> k -#^^{-1} C -[[jC(9)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K +#^^{-1} C -[[jC(9)]]-> (k -[[] + k:k(4):1]-> {}) where k implements K D := {} implements [J {j: jD}] jD = \@D _ -> k -#^^{-1} D -[[jD(10)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K +#^^{-1} D -[[jD(10)]]-> (k -[[] + k:k(4):1]-> {}) where k implements K E := {} implements [K {k: kE}] kE = \@E _ -> {} @@ -20,24 +20,24 @@ kF = \@F _ -> {} #^^{-1} F -[[kF(12)]]-> {} f = \flag, a, b -> -# ^ j | j implements J -# ^ j | j implements J +# ^ j where j implements J +# ^ j where j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) | j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) where j implements J, j1 has J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) where j implements J, j1 has J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K main = #^^^^{-1} {} it = \x -> -# ^^ k -[[it(21)]]-> {} | k implements K +# ^^ k -[[it(21)]]-> {} where k implements K (f A (@C {}) (@D {})) x -# ^ [A, B], C, D -[[f(13)]]-> (k -[[] + k:k(4):1]-> {}) | k implements K +# ^ [A, B], C, D -[[f(13)]]-> (k -[[] + k:k(4):1]-> {}) where k implements K if Bool.true then it (@E {}) # ^^ E -[[it(21)]]-> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt index 6c83ef6b6ae..57331a3945a 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt @@ -1,11 +1,11 @@ app "test" provides [main] to "./platform" -F has f : a, b -> ({} -> ({} -> {})) | a implements F, b implements G -G has g : b -> ({} -> {}) | b implements G +F has f : a, b -> ({} -> ({} -> {})) where a implements F, b implements G +G has g : b -> ({} -> {}) where b implements G Fo := {} implements [F {f}] f = \@Fo {}, b -> \{} -> g b -#^{-1} Fo#f(7): Fo, b -[[f(7)]]-> ({} -[[13 b]]-> ({} -[[] + b:g(4):2]-> {})) | b implements G +#^{-1} Fo#f(7): Fo, b -[[f(7)]]-> ({} -[[13 b]]-> ({} -[[] + b:g(4):2]-> {})) where b implements G Go := {} implements [G {g}] g = \@Go {} -> \{} -> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt index 618d29dcc33..56dd2e74789 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt @@ -1,11 +1,11 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a implements F, b implements G -G has g : b -> {} | b implements G +F has f : a -> (b -> {}) where a implements F, b implements G +G has g : b -> {} where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) where b implements G Go := {} implements [G {g}] g = \@Go {} -> {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt index 71dc02b2cca..4cdda675096 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt @@ -1,19 +1,19 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) | a implements F, b implements G -G has g : b -> {} | b implements G +F has f : a -> (b -> {}) where a implements F, b implements G +G has g : b -> {} where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g -#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G +#^{-1} Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) where b implements G Go := {} implements [G {g}] g = \@Go {} -> {} #^{-1} Go#g(8): Go -[[g(8)]]-> {} main = -#^^^^{-1} b -[[] + b:g(4):1]-> {} | b implements G +#^^^^{-1} b -[[] + b:g(4):1]-> {} where b implements G h = f (@Fo {}) -# ^ Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b implements G -# ^ b -[[] + b:g(4):1]-> {} | b implements G +# ^ Fo#f(7): Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) where b implements G +# ^ b -[[] + b:g(4):1]-> {} where b implements G h diff --git a/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt b/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt index 8653bb77c7c..0cfad58ac9d 100644 --- a/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt +++ b/crates/compiler/uitest/tests/ability/specialize/ranged_num_hash.txt @@ -2,4 +2,4 @@ app "test" provides [main] to "./platform" main = \h -> Hash.hash h 7 - # ^^^^^^^^^ Hash#Hash.hash(1): a, I64 -[[Hash.hashI64(13)]]-> a | a implements Hasher + # ^^^^^^^^^ Hash#Hash.hash(1): a, I64 -[[Hash.hashI64(13)]]-> a where a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt index 390df75dfbb..e3b4e8cdc81 100644 --- a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt +++ b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder.txt @@ -3,4 +3,4 @@ app "test" provides [main] to "./platform" main = toEncoder { a: "" } - # ^^^^^^^^^ Encoding#toEncoder(2): { a : Str } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt | fmt implements EncoderFormatting + # ^^^^^^^^^ Encoding#toEncoder(2): { a : Str } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt where fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt index ba43f3905f5..769296f3cf1 100644 --- a/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt +++ b/crates/compiler/uitest/tests/ability/specialize/record_to_encoder_with_nested_custom_impl.txt @@ -6,4 +6,4 @@ A := {} implements [Encoding {toEncoder}] toEncoder = \@A _ -> custom \b, _ -> b main = toEncoder { a: @A {} } - # ^^^^^^^^^ Encoding#toEncoder(2): { a : A } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt | fmt implements EncoderFormatting + # ^^^^^^^^^ Encoding#toEncoder(2): { a : A } -[[#Derived.toEncoder_{a}(0)]]-> Encoder fmt where fmt implements EncoderFormatting diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt index 00439c028a2..6903975585a 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -Id1 has id1 : a -> a | a implements Id1 -Id2 has id2 : a -> a | a implements Id2 +Id1 has id1 : a -> a where a implements Id1 +Id2 has id2 : a -> a where a implements Id2 A := {} implements [Id1 {id1}, Id2 {id2}] id1 = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt index 7fec6cf4b50..56fb6b5fed3 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a implements Id +Id has id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt index 7fd08456e29..744dc8ed30d 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a implements Id +Id has id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt index 172090ca5b9..76b859f1dea 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a implements Id +Id has id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} @@ -8,9 +8,9 @@ id = \@A {} -> @A {} main = alias1 = \x -> id x - # ^^ Id#id(2): a -[[] + a:id(2):1]-> a | a implements Id + # ^^ Id#id(2): a -[[] + a:id(2):1]-> a where a implements Id alias2 = \x -> alias1 x - # ^^^^^^ a -[[alias1(6)]]-> a | a implements Id + # ^^^^^^ a -[[alias1(6)]]-> a where a implements Id a : A a = alias2 (@A {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt index 004c1d70cb9..6304b2434db 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a | a implements Id +Id has id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt index 91e20eb8f94..3c6fdc4f492 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" Bounce has - ping : a -> a | a implements Bounce - pong : a -> a | a implements Bounce + ping : a -> a where a implements Bounce + pong : a -> a where a implements Bounce A := {} implements [Bounce {ping: pingA, pong: pongA}] diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt index a6af367fe12..43a739a59a6 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt @@ -1,8 +1,8 @@ app "test" provides [main] to "./platform" Bounce has - ping : a -> a | a implements Bounce - pong : a -> a | a implements Bounce + ping : a -> a where a implements Bounce + pong : a -> a where a implements Bounce A := {} implements [Bounce {ping, pong}] diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt index db9090568e0..a6373f7eafc 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Diverge has diverge : a -> a | a implements Diverge +Diverge has diverge : a -> a where a implements Diverge A := {} implements [Diverge {diverge}] diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt index 1b7828e9fe0..8b572588f3e 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt @@ -3,7 +3,7 @@ app "test" provides [main] to "./platform" Thunk a : {} -> a -Id has id : a -> Thunk a | a implements Id +Id has id : a -> Thunk a where a implements Id A := {} implements [Id {id}] id = \@A {} -> \{} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt index 2965caa4ad0..5431c48b1a8 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt @@ -3,7 +3,7 @@ app "test" provides [main] to "./platform" Thunk a : {} -> a -Id has id : a -> Thunk a | a implements Id +Id has id : a -> Thunk a where a implements Id A := {} implements [Id {id}] id = \@A {} -> \{} -> @A {} @@ -11,7 +11,7 @@ id = \@A {} -> \{} -> @A {} main = alias = \x -> id x - # ^^ Id#id(3): a -[[] + a:id(3):1]-> ({} -[[] + a:id(3):2]-> a) | a implements Id + # ^^ Id#id(3): a -[[] + a:id(3):1]-> ({} -[[] + a:id(3):2]-> a) where a implements Id a : A a = (alias (@A {})) {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt index eec59f31094..25352cdabf7 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt @@ -3,7 +3,7 @@ app "test" provides [main] to "./platform" Thunk a := {} -> a -Id has id : a -> Thunk a | a implements Id +Id has id : a -> Thunk a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @Thunk (\{} -> @A {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt index 79f047465a8..01dadc8d6f8 100644 --- a/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Default has default : {} -> a | a implements Default +Default has default : {} -> a where a implements Default A := {} implements [Default {default}] default = \{} -> @A {} diff --git a/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt b/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt index 48a4646cf99..6e99d30a577 100644 --- a/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt +++ b/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" X has - consume : a -> {} | a implements X + consume : a -> {} where a implements X O := {} implements [X {consume: consumeO}] @@ -12,8 +12,8 @@ P := {} implements [X {consume: consumeP}] consumeP = \@P {} -> {} caller = \x -> consume x -# ^ a | a implements X -# ^^^^^^^ X#consume(2): a -[[] + a:consume(2):1]-> {} | a implements X +# ^ a where a implements X +# ^^^^^^^ X#consume(2): a -[[] + a:consume(2):1]-> {} where a implements X main = { a: caller (@O {}), diff --git a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt index b904dabe305..366d156d8b0 100644 --- a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt +++ b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_annotation_only.txt @@ -1,7 +1,7 @@ app "test" provides [hash] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] diff --git a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt index 19fba98d6f8..db85fb9c612 100644 --- a/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt +++ b/crates/compiler/uitest/tests/solve/ability_checked_specialization_with_typed_body.txt @@ -1,7 +1,7 @@ app "test" provides [hash] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt index e8f330c0e38..72f5a2fe3d7 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_check.txt @@ -1,8 +1,8 @@ app "test" provides [hashEq] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash -hashEq : a, a -> Bool | a implements MHash +hashEq : a, a -> Bool where a implements MHash hashEq = \x, y -> hash x == hash y -#^^^^^^{-1} a, a -[[hashEq(0)]]-> Bool | a implements MHash +#^^^^^^{-1} a, a -[[hashEq(0)]]-> Bool where a implements MHash diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt index 5130b11d449..2344a9922c0 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer.txt @@ -1,7 +1,7 @@ app "test" provides [hashEq] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash hashEq = \x, y -> hash x == hash y -#^^^^^^{-1} a, a1 -[[hashEq(0)]]-> Bool | a implements MHash, a1 implements MHash +#^^^^^^{-1} a, a1 -[[hashEq(0)]]-> Bool where a implements MHash, a1 implements MHash diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt index 30c0829af39..4e55a6ded37 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_infer_usage.txt @@ -1,7 +1,7 @@ app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash hashEq = \x, y -> hash x == hash y diff --git a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt index 552c80b60b2..34e014097c0 100644 --- a/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt +++ b/crates/compiler/uitest/tests/solve/ability_constrained_in_non_member_multiple_specializations.txt @@ -1,7 +1,7 @@ app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash mulMHashes = \x, y -> hash x * hash y diff --git a/crates/compiler/uitest/tests/solve/ability_specialization_called.txt b/crates/compiler/uitest/tests/solve/ability_specialization_called.txt index 20b56e049be..632b5eac6cc 100644 --- a/crates/compiler/uitest/tests/solve/ability_specialization_called.txt +++ b/crates/compiler/uitest/tests/solve/ability_specialization_called.txt @@ -1,7 +1,7 @@ app "test" provides [zero] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] diff --git a/crates/compiler/uitest/tests/solve/alias_ability_member.txt b/crates/compiler/uitest/tests/solve/alias_ability_member.txt index ab5f5d7e9c2..550365d0667 100644 --- a/crates/compiler/uitest/tests/solve/alias_ability_member.txt +++ b/crates/compiler/uitest/tests/solve/alias_ability_member.txt @@ -1,9 +1,9 @@ app "test" provides [thething] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash thething = -#^^^^^^^^{-1} a -[[] + a:hash(2):1]-> U64 | a implements MHash +#^^^^^^^^{-1} a -[[] + a:hash(2):1]-> U64 where a implements MHash itis = hash itis diff --git a/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt b/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt index 01d4d571873..f4719ca9c7e 100644 --- a/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt +++ b/crates/compiler/uitest/tests/solve/alias_propagates_able_var.txt @@ -1,8 +1,8 @@ app "test" provides [zeroEncoder] to "./platform" -MEncoder fmt := List U8, fmt -> List U8 | fmt implements Format +MEncoder fmt := List U8, fmt -> List U8 where fmt implements Format -Format implements it : fmt -> {} | fmt implements Format +Format implements it : fmt -> {} where fmt implements Format zeroEncoder = @MEncoder \lst, _ -> lst -#^^^^^^^^^^^{-1} MEncoder a | a implements Format +#^^^^^^^^^^^{-1} MEncoder a where a implements Format diff --git a/crates/compiler/uitest/tests/solve/exposed_ability_name.txt b/crates/compiler/uitest/tests/solve/exposed_ability_name.txt index 875af03cea8..f22850b0097 100644 --- a/crates/compiler/uitest/tests/solve/exposed_ability_name.txt +++ b/crates/compiler/uitest/tests/solve/exposed_ability_name.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -MHash implements hash : a -> U64 | a implements MHash +MHash implements hash : a -> U64 where a implements MHash main = hash -# ^^^^ MHash#hash(2): a -[[] + a:hash(2):1]-> U64 | a implements MHash +# ^^^^ MHash#hash(2): a -[[] + a:hash(2):1]-> U64 where a implements MHash diff --git a/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt b/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt index b572ce562ca..adddd308cb0 100644 --- a/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt +++ b/crates/compiler/uitest/tests/solve/multiple_abilities_multiple_members_specializations.txt @@ -1,12 +1,12 @@ app "test" provides [hash, hash32, eq, le] to "./platform" MHash implements - hash : a -> U64 | a implements MHash - hash32 : a -> U32 | a implements MHash + hash : a -> U64 where a implements MHash + hash32 : a -> U32 where a implements MHash Ord implements - eq : a, a -> Bool | a implements Ord - le : a, a -> Bool | a implements Ord + eq : a, a -> Bool where a implements Ord + le : a, a -> Bool where a implements Ord Id := U64 implements [MHash {hash, hash32}, Ord {eq, le}] diff --git a/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt b/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt index 37b18653c07..5738eebcd61 100644 --- a/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt +++ b/crates/compiler/uitest/tests/solve/single_ability_multiple_members_specializations.txt @@ -1,8 +1,8 @@ app "test" provides [hash, hash32] to "./platform" MHash implements - hash : a -> U64 | a implements MHash - hash32 : a -> U32 | a implements MHash + hash : a -> U64 where a implements MHash + hash32 : a -> U32 where a implements MHash Id := U64 implements [MHash {hash, hash32}] diff --git a/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt b/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt index 190a4d2701b..a49c763de59 100644 --- a/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt +++ b/crates/compiler/uitest/tests/solve/single_ability_single_member_specializations.txt @@ -1,6 +1,6 @@ app "test" provides [hash] to "./platform" -MHash implements hash : a -> U64 | a implements MHash +MHash implements hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] diff --git a/crates/reporting/src/error/type.rs b/crates/reporting/src/error/type.rs index 2223bbd825d..378f6d902e7 100644 --- a/crates/reporting/src/error/type.rs +++ b/crates/reporting/src/error/type.rs @@ -403,7 +403,8 @@ fn underivable_hint<'b>( alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause to bind the type variable, like "), alloc.inline_type_block(alloc.concat([ - alloc.string("| ".to_string()), + alloc.keyword(roc_parse::keyword::WHERE), + alloc.space(), alloc.type_variable(v.clone()), alloc.space(), alloc.keyword(roc_parse::keyword::IMPLEMENTS), @@ -2755,7 +2756,13 @@ fn type_with_able_vars<'b>( doc.push(typ); for (i, (var, abilities)) in able.into_iter().enumerate() { - doc.push(alloc.string(if i == 0 { " | " } else { ", " }.to_string())); + if i == 0 { + doc.push(alloc.space()); + doc.push(alloc.keyword(roc_parse::keyword::WHERE)); + } else { + doc.push(alloc.string(",".to_string())); + } + doc.push(alloc.space()); doc.push(alloc.type_variable(var)); doc.push(alloc.space()); doc.push(alloc.keyword(roc_parse::keyword::IMPLEMENTS)); diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 6b3e7cd079c..bebad3e4abe 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -6488,7 +6488,7 @@ In roc, functions are always written as a lambda, like{} inference_var_conflict_in_rigid_links, indoc!( r#" - f : a -> (_ -> b) | a implements Eq + f : a -> (_ -> b) where a implements Eq f = \x -> \y -> if x == y then x else y f "# @@ -6499,17 +6499,17 @@ In roc, functions are always written as a lambda, like{} Something is off with the body of the `f` definition: - 4│ f : a -> (_ -> b) | a implements Eq + 4│ f : a -> (_ -> b) where a implements Eq 5│ f = \x -> \y -> if x == y then x else y ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The body is an anonymous function of type: - a -> a | a implements Eq, a implements Eq + a -> a where a implements Eq, a implements Eq But the type annotation on `f` says it should be: - a -> b | a implements Eq + a -> b where a implements Eq Tip: Your type annotation uses `b` and `a` as separate type variables. Your code seems to be saying they are the same though. Maybe they @@ -8207,7 +8207,7 @@ In roc, functions are always written as a lambda, like{} indoc!( r#" MEq implements - eq : a, a -> U64 | a implements MEq + eq : a, a -> U64 where a implements MEq 1 "# @@ -8219,7 +8219,7 @@ In roc, functions are always written as a lambda, like{} here: 4│ MEq implements - 5│ eq : a, a -> U64 | a implements MEq + 5│ eq : a, a -> U64 where a implements MEq ^ I suspect this line is not indented enough (by 1 spaces) @@ -8231,8 +8231,8 @@ In roc, functions are always written as a lambda, like{} indoc!( r#" MEq implements - eq : a, a -> U64 | a implements MEq - neq : a, a -> U64 | a implements MEq + eq : a, a -> U64 where a implements MEq + neq : a, a -> U64 where a implements MEq 1 "# @@ -8243,8 +8243,8 @@ In roc, functions are always written as a lambda, like{} I was partway through parsing an ability definition, but I got stuck here: - 5│ eq : a, a -> U64 | a implements MEq - 6│ neq : a, a -> U64 | a implements MEq + 5│ eq : a, a -> U64 where a implements MEq + 6│ neq : a, a -> U64 where a implements MEq ^ I suspect this line is indented too much (by 4 spaces)"# @@ -8255,7 +8255,7 @@ In roc, functions are always written as a lambda, like{} indoc!( r#" MEq implements - eq b c : a, a -> U64 | a implements MEq + eq b c : a, a -> U64 where a implements MEq 1 "# @@ -8267,7 +8267,7 @@ In roc, functions are always written as a lambda, like{} here: 4│ MEq implements - 5│ eq b c : a, a -> U64 | a implements MEq + 5│ eq b c : a, a -> U64 where a implements MEq ^ I was expecting to see a : annotating the signature of this value @@ -8417,7 +8417,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [] to "./platform" MHash a b c implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash "# ), @r###" @@ -8449,7 +8449,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash] to "./platform" - MHash implements hash : a, b -> Num.U64 | a implements MHash, b implements Bool.Bool + MHash implements hash : a, b -> Num.U64 where a implements MHash, b implements Bool.Bool "# ), @r###" @@ -8457,8 +8457,8 @@ In roc, functions are always written as a lambda, like{} The type referenced in this "implements" clause is not an ability: - 3│ MHash implements hash : a, b -> Num.U64 | a implements MHash, b implements Bool.Bool - ^^^^^^^^^ + 3│ MHash implements hash : a, b -> Num.U64 where a implements MHash, b implements Bool.Bool + ^^^^^^^^^ "### ); @@ -8468,7 +8468,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [ab1] to "./platform" - Ab1 implements ab1 : a -> {} | a implements Ab1, a implements Ab1 + Ab1 implements ab1 : a -> {} where a implements Ab1, a implements Ab1 "# ), @r#" @@ -8476,13 +8476,13 @@ In roc, functions are always written as a lambda, like{} The `a` name is first defined here: - 3│ Ab1 implements ab1 : a -> {} | a implements Ab1, a implements Ab1 - ^^^^^^^^^^^^^^^^ + 3│ Ab1 implements ab1 : a -> {} where a implements Ab1, a implements Ab1 + ^^^^^^^^^^^^^^^^ But then it's defined a second time here: - 3│ Ab1 implements ab1 : a -> {} | a implements Ab1, a implements Ab1 - ^^^^^^^^^^^^^^^^ + 3│ Ab1 implements ab1 : a -> {} where a implements Ab1, a implements Ab1 + ^^^^^^^^^^^^^^^^ Since these variables have the same name, it's easy to use the wrong one by accident. Give one of them a new name. @@ -8495,9 +8495,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [ab] to "./platform" - Ability implements ab : a -> U64 | a implements Ability + Ability implements ab : a -> U64 where a implements Ability - Ability implements ab1 : a -> U64 | a implements Ability + Ability implements ab1 : a -> U64 where a implements Ability "# ), @r#" @@ -8505,12 +8505,12 @@ In roc, functions are always written as a lambda, like{} The `Ability` name is first defined here: - 3│ Ability implements ab : a -> U64 | a implements Ability + 3│ Ability implements ab : a -> U64 where a implements Ability ^^^^^^^ But then it's defined a second time here: - 5│ Ability implements ab1 : a -> U64 | a implements Ability + 5│ Ability implements ab1 : a -> U64 where a implements Ability ^^^^^^^ Since these abilities have the same name, it's easy to use the wrong @@ -8561,7 +8561,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [] to "./platform" - MEq implements eq : a, b -> Bool.Bool | a implements MEq, b implements MEq + MEq implements eq : a, b -> Bool.Bool where a implements MEq, b implements MEq "# ), @r#" @@ -8570,8 +8570,8 @@ In roc, functions are always written as a lambda, like{} The definition of the ability member `eq` includes multiple variables bound to the `MEq`` ability:` - 3│ MEq implements eq : a, b -> Bool.Bool | a implements MEq, b implements MEq - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 3│ MEq implements eq : a, b -> Bool.Bool where a implements MEq, b implements MEq + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ability members can only bind one type variable to their parent ability. Otherwise, I wouldn't know what type implements an ability by @@ -8587,9 +8587,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [f] to "./platform" - MHash implements hash : (a | a implements MHash) -> Num.U64 + MHash implements hash : (a where a implements MHash) -> Num.U64 - f : a -> Num.U64 | a implements MHash + f : a -> Num.U64 where a implements MHash "# ), @r###" @@ -8597,8 +8597,8 @@ In roc, functions are always written as a lambda, like{} An `implements` clause is not allowed here: - 3│ MHash implements hash : (a | a implements MHash) -> Num.U64 - ^^^^^^^^^^^^^^^^^^ + 3│ MHash implements hash : (a where a implements MHash) -> Num.U64 + ^^^^^^^^^^^^^^^^^^ `implements` clauses can only be specified on the top-level type annotations. @@ -8608,7 +8608,7 @@ In roc, functions are always written as a lambda, like{} The definition of the ability member `hash` does not include an `implements` clause binding a type variable to the ability `MHash`: - 3│ MHash implements hash : (a | a implements MHash) -> Num.U64 + 3│ MHash implements hash : (a where a implements MHash) -> Num.U64 ^^^^ Ability members must include an `implements` clause binding a type @@ -8626,7 +8626,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [hash] to "./platform" - MHash implements hash : a -> U64 | a implements MHash + MHash implements hash : a -> U64 where a implements MHash Id := U32 implements [MHash {hash}] @@ -8658,8 +8658,8 @@ In roc, functions are always written as a lambda, like{} app "test" provides [eq, le] to "./platform" MEq implements - eq : a, a -> Bool | a implements MEq - le : a, a -> Bool | a implements MEq + eq : a, a -> Bool where a implements MEq + le : a, a -> Bool where a implements MEq Id := U64 implements [MEq {eq}] @@ -8687,7 +8687,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash hash = \_ -> 0u64 "# @@ -8712,7 +8712,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash, One, Two] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash One := {} implements [MHash {hash}] Two := {} implements [MHash {hash}] @@ -8748,7 +8748,7 @@ In roc, functions are always written as a lambda, like{} But the type annotation on `hash` says it must match: - a -> U64 | a implements MHash + a -> U64 where a implements MHash Note: The specialized type is too general, and does not provide a concrete type where a type variable is bound to an ability. @@ -8766,7 +8766,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash, One, Two] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash One := {} implements [MHash {hash}] Two := {} implements [MHash {hash}] @@ -8797,7 +8797,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [eq] to "./platform" MEq implements - eq : a, a -> Bool | a implements MEq + eq : a, a -> Bool where a implements MEq You := {} implements [MEq {eq}] AndI := {} @@ -8832,7 +8832,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] @@ -8866,7 +8866,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [noGoodVeryBadTerrible] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] @@ -8914,7 +8914,7 @@ In roc, functions are always written as a lambda, like{} main = MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash 123 "# @@ -8925,7 +8925,7 @@ In roc, functions are always written as a lambda, like{} This ability definition is not on the top-level of a module: 4│> MHash implements - 5│> hash : a -> U64 | a implements MHash + 5│> hash : a -> U64 where a implements MHash Abilities can only be defined on the top-level of a Roc module. "# @@ -8938,12 +8938,12 @@ In roc, functions are always written as a lambda, like{} app "test" provides [hash, hashable] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash Id := U64 implements [MHash {hash}] hash = \@Id n -> n - hashable : a | a implements MHash + hashable : a where a implements MHash hashable = @Id 15 "# ), @@ -8952,7 +8952,7 @@ In roc, functions are always written as a lambda, like{} Something is off with the body of the `hashable` definition: - 9│ hashable : a | a implements MHash + 9│ hashable : a where a implements MHash 10│ hashable = @Id 15 ^^^^^^ @@ -8962,7 +8962,7 @@ In roc, functions are always written as a lambda, like{} But the type annotation on `hashable` says it should be: - a | a implements MHash + a where a implements MHash Note: The type variable `a` says it can take on any value that implements the ability `MHash`. @@ -8979,7 +8979,7 @@ In roc, functions are always written as a lambda, like{} app "test" provides [result] to "./platform" MHash implements - hash : a -> U64 | a implements MHash + hash : a -> U64 where a implements MHash mulMHashes : MHash, MHash -> U64 mulMHashes = \x, y -> hash x * hash y @@ -9154,7 +9154,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [main] to "./platform" - Default implements default : {} -> a | a implements Default + Default implements default : {} -> a where a implements Default main = A := {} implements [Default {default}] @@ -9405,7 +9405,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq implements eq : a, a -> U64 | a implements MEq + MEq implements eq : a, a -> U64 where a implements MEq A := U8 implements [MEq {eq}] "# @@ -9441,7 +9441,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A, myMEq] to "./platform" - MEq implements eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool where a implements MEq A := U8 implements [ MEq {eq: aMEq} ] @@ -9482,7 +9482,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A, myMEq] to "./platform" - MEq implements eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool where a implements MEq A := U8 implements [ MEq {eq ? aMEq} ] @@ -9560,7 +9560,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq implements eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool where a implements MEq A := U8 implements [ MEq {eq : Bool.eq} ] "# @@ -9595,7 +9595,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq implements eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool where a implements MEq A := U8 implements [ MEq {eq : \m, n -> m == n} ] "# @@ -9632,7 +9632,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - MEq implements eq : a, a -> Bool | a implements MEq + MEq implements eq : a, a -> Bool where a implements MEq A := U8 implements [ MEq {eq: eqA, eq: eqA} ] @@ -9685,7 +9685,7 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [A] to "./platform" - Ab implements ab : a -> a | a implements Ab + Ab implements ab : a -> a where a implements Ab A := {} implements [Ab] "# @@ -9946,9 +9946,9 @@ In roc, functions are always written as a lambda, like{} r#" app "test" provides [x] to "./platform" - Foo implements foo : a -> a | a implements Foo + Foo implements foo : a -> a where a implements Foo - F a b := b | a implements Foo + F a b := b where a implements Foo MHash := {} @@ -10476,7 +10476,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [hash, Id] to "./platform" - MHash implements hash : a -> U64 | a implements MHash + MHash implements hash : a -> U64 where a implements MHash Id := {} @@ -10502,7 +10502,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [hash, Id, Id2] to "./platform" - MHash implements hash : a -> U64 | a implements MHash + MHash implements hash : a -> U64 where a implements MHash Id := {} implements [MHash {hash}] Id2 := {} @@ -10659,7 +10659,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder (a -> a) fmt | fmt implements DecoderFormatting + myDecoder : Decoder (a -> a) fmt where fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -10690,7 +10690,7 @@ I recommend using camelCase. It's the standard style in Roc code! A := {} main = - myDecoder : Decoder {x : A} fmt | fmt implements DecoderFormatting + myDecoder : Decoder {x : A} fmt where fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -10909,7 +10909,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder {x : Str, y ? Str} fmt | fmt implements DecoderFormatting + myDecoder : Decoder {x : Str, y ? Str} fmt where fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -11323,7 +11323,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Hash + foo : a -> {} where a implements Hash main = foo {a: "", b: 1} "# @@ -11337,7 +11337,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Hash + foo : a -> {} where a implements Hash t : [A {}, B U8 U64, C Str] @@ -11353,7 +11353,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Hash + foo : a -> {} where a implements Hash main = foo (\x -> x) "# @@ -11380,7 +11380,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Hash + foo : a -> {} where a implements Hash main = foo (A (\x -> x) B) "# @@ -11413,7 +11413,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Hash + foo : a -> {} where a implements Hash main = foo ("", 1) "# @@ -11426,7 +11426,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Hash + foo : a -> {} where a implements Hash main = foo ("", \{} -> {}) "# @@ -11709,7 +11709,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Eq + foo : a -> {} where a implements Eq main = foo {a: "", b: 1} "# @@ -11723,7 +11723,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Eq + foo : a -> {} where a implements Eq t : [A {}, B U8 U64, C Str] @@ -11739,7 +11739,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Eq + foo : a -> {} where a implements Eq main = foo (\x -> x) "# @@ -11766,7 +11766,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Eq + foo : a -> {} where a implements Eq main = foo (A (\x -> x) B) "# @@ -11845,7 +11845,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Eq + foo : a -> {} where a implements Eq main = foo ("", 1) "# @@ -11858,7 +11858,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - foo : a -> {} | a implements Eq + foo : a -> {} where a implements Eq main = foo ("", 1.0f64) "# @@ -11938,7 +11938,7 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [f] to "./platform" - F a : a | a implements Hash + F a : a where a implements Hash f : F ({} -> {}) "# @@ -12037,7 +12037,7 @@ I recommend using camelCase. It's the standard style in Roc code! duplicate_ability_in_has_clause, indoc!( r#" - f : a -> {} | a implements Hash & Hash + f : a -> {} where a implements Hash & Hash f "# @@ -12048,8 +12048,8 @@ I recommend using camelCase. It's the standard style in Roc code! I already saw that this type variable is bound to the `Hash` ability once before: - 4│ f : a -> {} | a implements Hash & Hash - ^^^^ + 4│ f : a -> {} where a implements Hash & Hash + ^^^^ Abilities only need to bound to a type variable once in an `implements` clause! @@ -12062,9 +12062,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - g : x -> x | x implements Decoding & Encoding + g : x -> x where x implements Decoding & Encoding - main : x -> x | x implements Encoding + main : x -> x where x implements Encoding main = \x -> g x "# ), @@ -12078,11 +12078,11 @@ I recommend using camelCase. It's the standard style in Roc code! This `x` value is a: - x | x implements Encoding + x where x implements Encoding But `g` needs its 1st argument to be: - x | x implements Encoding & Decoding + x where x implements Encoding & Decoding Note: The type variable `x` says it can take on any value that implements only the ability `Encoding`. @@ -12099,9 +12099,9 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - g : x -> x | x implements Decoding & Encoding & Hash + g : x -> x where x implements Decoding & Encoding & Hash - main : x -> x | x implements Encoding + main : x -> x where x implements Encoding main = \x -> g x "# ), @@ -12115,11 +12115,11 @@ I recommend using camelCase. It's the standard style in Roc code! This `x` value is a: - x | x implements Encoding + x where x implements Encoding But `g` needs its 1st argument to be: - x | x implements Hash & Encoding & Decoding + x where x implements Hash & Encoding & Decoding Note: The type variable `x` says it can take on any value that implements only the ability `Encoding`. @@ -12136,10 +12136,10 @@ I recommend using camelCase. It's the standard style in Roc code! r#" app "test" provides [main] to "./platform" - f : x -> x | x implements Hash - g : x -> x | x implements Decoding & Encoding + f : x -> x where x implements Hash + g : x -> x where x implements Decoding & Encoding - main : x -> x | x implements Hash & Encoding + main : x -> x where x implements Hash & Encoding main = \x -> g (f x) "# ), @@ -12153,11 +12153,11 @@ I recommend using camelCase. It's the standard style in Roc code! This `f` call produces: - x | x implements Hash & Encoding + x where x implements Hash & Encoding But `g` needs its 1st argument to be: - x | x implements Encoding & Decoding + x where x implements Encoding & Decoding Note: The type variable `x` says it can take on any value that implements only the abilities `Hash` and `Encoding`. @@ -12905,7 +12905,7 @@ I recommend using camelCase. It's the standard style in Roc code! Tip: This type variable is not bound to `Eq`. Consider adding an `implements` clause to bind the type variable, like - `| e implements Bool.Eq` + `where e implements Bool.Eq` "### ); @@ -13371,7 +13371,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder Nat fmt | fmt implements DecoderFormatting + myDecoder : Decoder Nat fmt where fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -13435,7 +13435,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder (U32, Str) fmt | fmt implements DecoderFormatting + myDecoder : Decoder (U32, Str) fmt where fmt implements DecoderFormatting myDecoder = decoder myDecoder @@ -13450,7 +13450,7 @@ I recommend using camelCase. It's the standard style in Roc code! app "test" imports [Decode.{decoder}] provides [main] to "./platform" main = - myDecoder : Decoder (U32, {} -> {}) fmt | fmt implements DecoderFormatting + myDecoder : Decoder (U32, {} -> {}) fmt where fmt implements DecoderFormatting myDecoder = decoder myDecoder diff --git a/examples/cli/cli-platform/Env.roc b/examples/cli/cli-platform/Env.roc index 061ab69b28b..50af317d8c9 100644 --- a/examples/cli/cli-platform/Env.roc +++ b/examples/cli/cli-platform/Env.roc @@ -65,7 +65,7 @@ var = \name -> ## - comma-separated lists (of either strings or numbers), as long as there are no spaces after the commas ## ## Trying to decode into any other types will always fail with a `DecodeErr`. -decode : Str -> Task val [VarNotFound, DecodeErr DecodeError] | val implements Decoding +decode : Str -> Task val [VarNotFound, DecodeErr DecodeError] where val implements Decoding decode = \name -> Effect.envVar name |> Effect.map @@ -120,4 +120,4 @@ dict = # decode all the required vars only, and then decode the optional ones separately some other way. # Alternatively, it could make sense to have some sort of tag union convention here, e.g. # if decoding into a tag union of [Present val, Missing], then it knows what to do. -# decodeAll : Task val [] [EnvDecodingFailed Str] [Env] | val implements Decoding +# decodeAll : Task val [] [EnvDecodingFailed Str] [Env] where val implements Decoding diff --git a/examples/cli/cli-platform/File.roc b/examples/cli/cli-platform/File.roc index 97d8841792f..b5e367f889c 100644 --- a/examples/cli/cli-platform/File.roc +++ b/examples/cli/cli-platform/File.roc @@ -26,7 +26,7 @@ WriteErr : InternalFile.WriteErr ## This opens the file first and closes it after writing to it. ## ## To write unformatted bytes to a file, you can use [File.writeBytes] instead. -write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] | val implements Encode.Encoding, fmt implements Encode.EncoderFormatting +write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] where val implements Encode.Encoding, fmt implements Encode.EncoderFormatting write = \path, val, fmt -> bytes = Encode.toBytes val fmt @@ -119,7 +119,7 @@ readUtf8 = \path -> # Str # [FileReadErr Path ReadErr, FileReadDecodeErr Path [Leftover (List U8)]Decode.DecodeError ] # [Read [File]] -# | val implements Decode.Decoding, fmt implements Decode.DecoderFormatting +# where val implements Decode.Decoding, fmt implements Decode.DecoderFormatting # read = \path, fmt -> # effect = Effect.map (Effect.fileReadBytes (InternalPath.toBytes path)) \result -> # when result is diff --git a/examples/cli/cli-platform/Http.roc b/examples/cli/cli-platform/Http.roc index 372d10a4816..04c7132aee7 100644 --- a/examples/cli/cli-platform/Http.roc +++ b/examples/cli/cli-platform/Http.roc @@ -56,7 +56,7 @@ stringBody : [MimeType Str], Str -> Body stringBody = \mimeType, str -> Body mimeType (Str.toUtf8 str) -# jsonBody : a -> Body | a implements Encoding +# jsonBody : a -> Body where a implements Encoding # jsonBody = \val -> # Body (MimeType "application/json") (Encode.toBytes val Json.format) # diff --git a/examples/python-interop/platform/main.roc b/examples/python-interop/platform/main.roc index 949cbe8dd24..5cfaa5f43b6 100644 --- a/examples/python-interop/platform/main.roc +++ b/examples/python-interop/platform/main.roc @@ -1,5 +1,5 @@ platform "python-interop" - requires {} { main : arg -> ret | arg implements Decoding, ret implements Encoding } + requires {} { main : arg -> ret where arg implements Decoding, ret implements Encoding } exposes [] packages {} imports [Json] diff --git a/examples/ruby-interop/platform/main.roc b/examples/ruby-interop/platform/main.roc index 1cae530d890..c46ca8a0bff 100644 --- a/examples/ruby-interop/platform/main.roc +++ b/examples/ruby-interop/platform/main.roc @@ -1,5 +1,5 @@ platform "ruby-interop" - requires {} { main : arg -> ret | arg implements Decoding, ret implements Encoding } + requires {} { main : arg -> ret where arg implements Decoding, ret implements Encoding } exposes [] packages {} imports [Json] diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc index bb2fab07122..d126741b2f0 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc @@ -84,7 +84,7 @@ DiffState state : { rendered : RenderedTree state, patches : List Patch } # ------------------------------- # INITIALISATION # ------------------------------- -initClientApp : List U8, App state initData -> Effect (PlatformState state initData) | initData implements Decoding +initClientApp : List U8, App state initData -> Effect (PlatformState state initData) where initData implements Decoding initClientApp = \json, app -> # Initialise the Roc representation of the rendered DOM, and calculate patches (for event listeners) { state, rendered, patches } = @@ -100,7 +100,7 @@ initClientApp = \json, app -> } # Testable helper function to initialise the app -initClientAppHelp : List U8, App state initData -> { state, rendered : RenderedTree state, patches : List Patch } | initData implements Decoding +initClientAppHelp : List U8, App state initData -> { state, rendered : RenderedTree state, patches : List Patch } where initData implements Decoding initClientAppHelp = \json, app -> state = json @@ -200,7 +200,7 @@ JsEventResult state initData : { } ## Dispatch a JavaScript event to a Roc handler, given the handler ID and some JSON event data. -dispatchEvent : PlatformState state initData, List (List U8), HandlerId -> Effect (JsEventResult state initData) | initData implements Decoding +dispatchEvent : PlatformState state initData, List (List U8), HandlerId -> Effect (JsEventResult state initData) where initData implements Decoding dispatchEvent = \platformState, eventData, handlerId -> { app, state, rendered } = platformState diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Server.roc b/examples/virtual-dom-wip/platform/Html/Internal/Server.roc index 05f1493d110..a9541197b25 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Server.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Server.roc @@ -57,7 +57,7 @@ appendRenderedStaticAttr = \{ buffer, styles }, attr -> # ------------------------------- # INITIALISATION # ------------------------------- -initServerApp : App state initData, initData, Str -> Result (Html []) [InvalidDocument] | initData implements Encoding +initServerApp : App state initData, initData, Str -> Result (Html []) [InvalidDocument] where initData implements Encoding initServerApp = \app, initData, hostJavaScript -> initData |> Ok @@ -66,7 +66,7 @@ initServerApp = \app, initData, hostJavaScript -> |> translateStatic |> insertRocScript initData app.wasmUrl hostJavaScript -insertRocScript : Html [], initData, Str, Str -> Result (Html []) [InvalidDocument] | initData implements Encoding +insertRocScript : Html [], initData, Str, Str -> Result (Html []) [InvalidDocument] where initData implements Encoding insertRocScript = \document, initData, wasmUrl, hostJavaScript -> encode = \value -> diff --git a/examples/virtual-dom-wip/platform/client-side.roc b/examples/virtual-dom-wip/platform/client-side.roc index 73e8603f53f..bfa0c19fb8a 100644 --- a/examples/virtual-dom-wip/platform/client-side.roc +++ b/examples/virtual-dom-wip/platform/client-side.roc @@ -26,7 +26,7 @@ ToHost state initData : { } # TODO: naming the type variables causes a type 'mismatch' -# main : FromHost state initData -> Effect (ToHost state initData) | initData implements Decoding & Encoding +# main : FromHost state initData -> Effect (ToHost state initData) where initData implements Decoding & Encoding main : FromHost _ _ -> Effect (ToHost _ _) main = \fromHost -> if fromHost.isInitEvent then diff --git a/www/generate_tutorial/src/tutorial.roc b/www/generate_tutorial/src/tutorial.roc index f8bc3117ef5..d4f012045d0 100644 --- a/www/generate_tutorial/src/tutorial.roc +++ b/www/generate_tutorial/src/tutorial.roc @@ -1,5 +1,5 @@ app "roc-tutorial" - packages { pf: "../../../examples/static-site-gen/platform/main.roc" } + packages { pf: "../../../examples/static-site-gen/platform/main.roc" } imports [ pf.Html.{ html, head, body, footer, script, div, main, p, section, h1, h2, label, ol, input, text, nav, a, li, link, meta }, pf.Html.Attributes.{ content, name, for, id, type, href, rel, lang, class, title, charset, src }, @@ -28,8 +28,8 @@ view = \htmlContent -> text htmlContent, ], footer [] [ - text "Made by people who like to make nice things. © 2022" - ] + text "Made by people who like to make nice things. © 2022", + ], ], script [src "/site.js"] [], ] @@ -62,26 +62,26 @@ viewTutorialStart = tocLinks = { tag, value } <- List.map [ - { tag: "#installation", value: "Installation" }, - { tag: "#strings-and-numbers", value: "Strings and Numbers" }, - { tag: "#building-an-application", value: "Building an Application" }, - { tag: "#defining-functions", value: "Defining Functions" }, - { tag: "#if-then-else", value: "if-then-else" }, - { tag: "#debugging", value: "Debugging" }, - { tag: "#records", value: "Records" }, - { tag: "#tags", value: "Tags & Pattern Matching" }, - { tag: "#booleans", value: "Booleans" }, - { tag: "#lists", value: "Lists" }, - { tag: "#types", value: "Types" }, - { tag: "#numeric-types", value: "Numeric Types" }, - { tag: "#crashing", value: "Crashing" }, - { tag: "#tests-and-expectations", value: "Tests and Expectations" }, - { tag: "#modules", value: "Modules" }, - { tag: "#tasks", value: "Tasks" }, - { tag: "#abilities", value: "Abilities" }, - { tag: "#appendix-advanced-concepts", value: "Advanced Concepts" }, - { tag: "#operator-desugaring-table", value: "Operator Desugaring Table" }, - ] + { tag: "#installation", value: "Installation" }, + { tag: "#strings-and-numbers", value: "Strings and Numbers" }, + { tag: "#building-an-application", value: "Building an Application" }, + { tag: "#defining-functions", value: "Defining Functions" }, + { tag: "#if-then-else", value: "if-then-else" }, + { tag: "#debugging", value: "Debugging" }, + { tag: "#records", value: "Records" }, + { tag: "#tags", value: "Tags & Pattern Matching" }, + { tag: "#booleans", value: "Booleans" }, + { tag: "#lists", value: "Lists" }, + { tag: "#types", value: "Types" }, + { tag: "#numeric-types", value: "Numeric Types" }, + { tag: "#crashing", value: "Crashing" }, + { tag: "#tests-and-expectations", value: "Tests and Expectations" }, + { tag: "#modules", value: "Modules" }, + { tag: "#tasks", value: "Tasks" }, + { tag: "#abilities", value: "Abilities" }, + { tag: "#appendix-advanced-concepts", value: "Advanced Concepts" }, + { tag: "#operator-desugaring-table", value: "Operator Desugaring Table" }, + ] li [] [ a [href tag] [text value], @@ -98,8 +98,8 @@ tutorialIntro = p [] [text "This tutorial will teach you how to build Roc applications. Along the way, you'll learn how to write tests, use the REPL, and more!"], ], section [] [ - h2 [ id "installation" ] [ - a [href "#installation"] [text "Installation"] + h2 [id "installation"] [ + a [href "#installation"] [text "Installation"], ], p [] [ text "Roc doesn’t have a numbered release or an installer yet, but you can follow the install instructions for your OS", @@ -108,7 +108,7 @@ tutorialIntro = a [href "https://roc.zulipchat.com/#narrow/stream/231634-beginners"] [text " #beginners "], text "on", a [href "https://roc.zulipchat.com/"] [text " Roc Zulip Chat "], - text "and ask for assistance!" - ] + text "and ask for assistance!", + ], ], ] From afa5aaba94519a7a3683f9cd6dc655ead951dd95 Mon Sep 17 00:00:00 2001 From: Bryce Miller Date: Sat, 10 Jun 2023 13:30:54 -0400 Subject: [PATCH 46/55] has -> implements --- crates/compiler/parse/src/ast.rs | 4 ++-- crates/compiler/parse/src/expr.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 662d5de071f..b3935ec35c1 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -1681,11 +1681,11 @@ impl<'a> Malformed for TypeDef<'a> { } => header.is_malformed() || typ.is_malformed() || derived.is_malformed(), TypeDef::Ability { header, - loc_implements: loc_has, + loc_implements, members, } => { header.is_malformed() - || loc_has.is_malformed() + || loc_implements.is_malformed() || members.iter().any(|member| member.is_malformed()) } } diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 6b279cef38f..31bbc892908 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -617,14 +617,14 @@ pub fn parse_single_def<'a>( }; if let Some((name, name_region, args)) = opt_tag_and_args { - if let Ok((_, loc_has, state)) = + if let Ok((_, loc_implements, state)) = loc_implements_parser().parse(arena, state.clone(), min_indent) { let (_, (type_def, def_region), state) = finish_parsing_ability_def_help( min_indent, Loc::at(name_region, name), args, - loc_has, + loc_implements, arena, state, )?; @@ -1370,7 +1370,7 @@ fn finish_parsing_ability_def_help<'a>( start_column: u32, name: Loc<&'a str>, args: &'a [Loc>], - loc_has: Loc>, + loc_implements: Loc>, arena: &'a Bump, state: State<'a>, ) -> ParseResult<'a, (TypeDef<'a>, Region), EExpr<'a>> { @@ -1408,7 +1408,7 @@ fn finish_parsing_ability_def_help<'a>( let def_region = Region::span_across(&name.region, &demands.last().unwrap().typ.region); let type_def = TypeDef::Ability { header: TypeHeader { name, vars: args }, - loc_implements: loc_has, + loc_implements, members: demands.into_bump_slice(), }; From 841cf8c74e768bbc047d37bf73d5de62dead4f98 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 20:20:55 -0400 Subject: [PATCH 47/55] Drop redundant import --- crates/compiler/test_gen/src/gen_tags.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/crates/compiler/test_gen/src/gen_tags.rs b/crates/compiler/test_gen/src/gen_tags.rs index b273461464e..67be6437715 100644 --- a/crates/compiler/test_gen/src/gen_tags.rs +++ b/crates/compiler/test_gen/src/gen_tags.rs @@ -17,8 +17,6 @@ use roc_mono::layout::{LayoutRepr, STLayoutInterner}; #[cfg(test)] use roc_std::{RocList, RocStr, U128}; -use crate::helpers::with_larger_debug_stack; - #[test] fn width_and_alignment_u8_u8() { use roc_mono::layout::Layout; @@ -2257,15 +2255,15 @@ fn recursive_tag_id_in_allocation_basic() { main = when x is - A _ -> "A" - B _ -> "B" - C _ -> "C" - D _ -> "D" - E _ -> "E" - F _ -> "F" - G _ -> "G" - H _ -> "H" - I _ -> "I" + A _ -> "A" + B _ -> "B" + C _ -> "C" + D _ -> "D" + E _ -> "E" + F _ -> "F" + G _ -> "G" + H _ -> "H" + I _ -> "I" "### ), RocStr::from("H"), From 6c05307a7bc1d73606b85d1cc2d8ec2f22e26c0e Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 20:36:14 -0400 Subject: [PATCH 48/55] Drop redundant import --- crates/compiler/test_gen/src/gen_list.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index 52a57d48e53..25f89869b7d 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -3822,8 +3822,6 @@ mod pattern_match { #[cfg(feature = "gen-dev")] use crate::helpers::dev::assert_evals_to; - use crate::helpers::with_larger_debug_stack; - use super::RocList; #[test] From 6ba4aebb3ba2079b53ef85e84066d365849de49a Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 20:54:35 -0400 Subject: [PATCH 49/55] roc format --- crates/compiler/builtins/roc/Dict.roc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 91e08bef32d..593e37d1397 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -241,8 +241,7 @@ clear = \@Dict { metadata, dataIndices, data } -> ## Convert each value in the dictionary to something new, by calling a conversion ## function on each of them which receives both the key and the old value. Then return a ## new dictionary containing the same keys and the converted values. -map : Dict k a, (k, a -> b) -> Dict k b - where k implements Hash & Eq, b implements Hash & Eq +map : Dict k a, (k, a -> b) -> Dict k b where k implements Hash & Eq, b implements Hash & Eq map = \dict, transform -> init = withCapacity (capacity dict) @@ -254,8 +253,7 @@ map = \dict, transform -> ## (using [Dict.insertAll]) into one dictionary. ## ## You may know a similar function named `concatMap` in other languages. -joinMap : Dict a b, (a, b -> Dict x y) -> Dict x y - where a implements Hash & Eq, x implements Hash & Eq +joinMap : Dict a b, (a, b -> Dict x y) -> Dict x y where a implements Hash & Eq, x implements Hash & Eq joinMap = \dict, transform -> init = withCapacity (capacity dict) # Might be a pessimization From 315d185b2b0b446c3a21dbb327f6615631b2c1f9 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 21:17:16 -0400 Subject: [PATCH 50/55] Fix test --- crates/compiler/test_syntax/tests/test_fmt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/test_syntax/tests/test_fmt.rs b/crates/compiler/test_syntax/tests/test_fmt.rs index d5bd7ad1f31..f824a220651 100644 --- a/crates/compiler/test_syntax/tests/test_fmt.rs +++ b/crates/compiler/test_syntax/tests/test_fmt.rs @@ -5565,7 +5565,7 @@ mod test_fmt { expr_formats_same(indoc!( r#" A := a where a implements Other - has [Eq { eq }, Hash { hash }] + implements [Eq { eq }, Hash { hash }] 0 "# From 0176b9310d22b801d046da01d7d9330655d2f0e8 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 21:51:01 -0400 Subject: [PATCH 51/55] Update snapshot tests --- ...lity_demand_value_has_args.expr.result-ast | 2 +- ...ds_not_indented_with_first.expr.result-ast | 2 +- ...demand_not_indented_enough.expr.result-ast | 2 +- ...y_non_signature_expression.expr.result-ast | 2 +- ...and_signature_is_multiline.expr.result-ast | 14 +- .../pass/ability_multi_line.expr.result-ast | 22 +- .../pass/ability_single_line.expr.result-ast | 22 +- .../pass/ability_two_in_a_row.expr.result-ast | 44 ++-- .../opaque_has_abilities.expr.formatted.roc | 8 +- .../pass/opaque_has_abilities.expr.result-ast | 224 +++++++++--------- .../where_clause_function.expr.result-ast | 12 +- ...e_multiple_bound_abilities.expr.result-ast | 54 ++--- .../where_clause_multiple_has.expr.result-ast | 24 +- ...ple_has_across_newlines.expr.formatted.roc | 2 +- ...ltiple_has_across_newlines.expr.result-ast | 24 +- .../where_clause_non_function.expr.result-ast | 12 +- .../where_clause_on_newline.expr.result-ast | 12 +- 17 files changed, 241 insertions(+), 241 deletions(-) diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.result-ast index 3cb44e1fdf0..1e781bb5798 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demand_value_has_args.expr.result-ast @@ -1 +1 @@ -Expr(Ability(DemandColon(@15), @7), @0) \ No newline at end of file +Expr(Ability(DemandColon(@22), @14), @0) \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.result-ast index b4df5acd380..4d5187ee9f9 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_demands_not_indented_with_first.expr.result-ast @@ -1 +1 @@ -Expr(Ability(DemandAlignment(4, @49), @40), @0) \ No newline at end of file +Expr(Ability(DemandAlignment(4, @67), @58), @0) \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.result-ast index f069010c695..d3fb65ba184 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_first_demand_not_indented_enough.expr.result-ast @@ -1 +1 @@ -Expr(Ability(DemandAlignment(-1, @8), @7), @0) \ No newline at end of file +Expr(Ability(DemandAlignment(-1, @15), @14), @0) \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.result-ast index a66a3a05e51..08763b5ffbf 100644 --- a/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/fail/ability_non_signature_expression.expr.result-ast @@ -1 +1 @@ -Expr(Ability(DemandName(@12), @7), @0) \ No newline at end of file +Expr(Ability(DemandName(@19), @14), @0) \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.result-ast index 7f97d785007..03168073e5f 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_demand_signature_is_multiline.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(0), ], regions: [ - @0-36, + @0-43, ], space_before: [ Slice(start = 0, length = 0), @@ -19,18 +19,18 @@ Defs( name: @0-4 "Hash", vars: [], }, - loc_has: @5-8 Has, + loc_implements: @5-15 Implements, members: [ AbilityMember { - name: @11-15 SpaceBefore( + name: @18-22 SpaceBefore( "hash", [ Newline, ], ), - typ: @18-36 Function( + typ: @25-43 Function( [ - @18-19 SpaceAfter( + @25-26 SpaceAfter( BoundVariable( "a", ), @@ -39,7 +39,7 @@ Defs( ], ), ], - @33-36 Apply( + @40-43 Apply( "", "U64", [], @@ -51,7 +51,7 @@ Defs( ], value_defs: [], }, - @38-39 SpaceBefore( + @45-46 SpaceBefore( Num( "1", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.result-ast index 35bbb58f043..9203211925a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_multi_line.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(0), ], regions: [ - @0-45, + @0-52, ], space_before: [ Slice(start = 0, length = 0), @@ -19,22 +19,22 @@ Defs( name: @0-4 "Hash", vars: [], }, - loc_has: @5-8 Has, + loc_implements: @5-15 Implements, members: [ AbilityMember { - name: @11-15 SpaceBefore( + name: @18-22 SpaceBefore( "hash", [ Newline, ], ), - typ: @18-26 Function( + typ: @25-33 Function( [ - @18-19 BoundVariable( + @25-26 BoundVariable( "a", ), ], - @23-26 Apply( + @30-33 Apply( "", "U64", [], @@ -42,19 +42,19 @@ Defs( ), }, AbilityMember { - name: @29-34 SpaceBefore( + name: @36-41 SpaceBefore( "hash2", [ Newline, ], ), - typ: @37-45 Function( + typ: @44-52 Function( [ - @37-38 BoundVariable( + @44-45 BoundVariable( "a", ), ], - @42-45 Apply( + @49-52 Apply( "", "U64", [], @@ -66,7 +66,7 @@ Defs( ], value_defs: [], }, - @47-48 SpaceBefore( + @54-55 SpaceBefore( Num( "1", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.result-ast index e450865a13d..2847f04b1dc 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_single_line.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(0), ], regions: [ - @0-37, + @0-55, ], space_before: [ Slice(start = 0, length = 0), @@ -19,28 +19,28 @@ Defs( name: @0-4 "Hash", vars: [], }, - loc_has: @5-8 Has, + loc_implements: @5-15 Implements, members: [ AbilityMember { - name: @9-13 "hash", - typ: @16-37 Where( - @16-24 Function( + name: @16-20 "hash", + typ: @23-55 Where( + @23-31 Function( [ - @16-17 BoundVariable( + @23-24 BoundVariable( "a", ), ], - @21-24 Apply( + @28-31 Apply( "", "U64", [], ), ), [ - @27-37 HasClause { - var: @27-28 "a", + @38-55 ImplementsClause { + var: @38-39 "a", abilities: [ - @33-37 Apply( + @51-55 Apply( "", "Hash", [], @@ -55,7 +55,7 @@ Defs( ], value_defs: [], }, - @39-40 SpaceBefore( + @57-58 SpaceBefore( Num( "1", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.result-ast index cce2f989e21..d4285ec53d1 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/ability_two_in_a_row.expr.result-ast @@ -5,8 +5,8 @@ Defs( Index(1), ], regions: [ - @0-33, - @35-68, + @0-51, + @53-104, ], space_before: [ Slice(start = 0, length = 0), @@ -26,27 +26,27 @@ Defs( name: @0-3 "Ab1", vars: [], }, - loc_has: @4-7 Has, + loc_implements: @4-14 Implements, members: [ AbilityMember { - name: @8-11 "ab1", - typ: @14-33 Where( - @14-21 Function( + name: @15-18 "ab1", + typ: @21-51 Where( + @21-28 Function( [ - @14-15 BoundVariable( + @21-22 BoundVariable( "a", ), ], - @19-21 Record { + @26-28 Record { fields: [], ext: None, }, ), [ - @24-33 HasClause { - var: @24-25 "a", + @35-51 ImplementsClause { + var: @35-36 "a", abilities: [ - @30-33 Apply( + @48-51 Apply( "", "Ab1", [], @@ -60,30 +60,30 @@ Defs( }, Ability { header: TypeHeader { - name: @35-38 "Ab2", + name: @53-56 "Ab2", vars: [], }, - loc_has: @39-42 Has, + loc_implements: @57-67 Implements, members: [ AbilityMember { - name: @43-46 "ab2", - typ: @49-68 Where( - @49-56 Function( + name: @68-71 "ab2", + typ: @74-104 Where( + @74-81 Function( [ - @49-50 BoundVariable( + @74-75 BoundVariable( "a", ), ], - @54-56 Record { + @79-81 Record { fields: [], ext: None, }, ), [ - @59-68 HasClause { - var: @59-60 "a", + @88-104 ImplementsClause { + var: @88-89 "a", abilities: [ - @65-68 Apply( + @101-104 Apply( "", "Ab2", [], @@ -98,7 +98,7 @@ Defs( ], value_defs: [], }, - @70-71 SpaceBefore( + @106-107 SpaceBefore( Num( "1", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc index ce68feedbfa..bc1b9655e7a 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.formatted.roc @@ -1,10 +1,10 @@ A := U8 implements [Eq, Hash] A := a where a implements Other - implements [Eq, Hash] + implements [Eq, Hash] A := a where a implements Other - implements [Eq, Hash] + implements [Eq, Hash] A := U8 implements [Eq { eq }, Hash { hash }] @@ -17,8 +17,8 @@ A := U8 implements [Hash, Eq { eq, eq1 }] A := U8 implements [] A := a where a implements Other - implements [Eq { eq }, Hash { hash }] + implements [Eq { eq }, Hash { hash }] A := U8 implements [Eq {}] -0 +0 \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.result-ast index b9a9bf4520f..6426fd40e66 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/opaque_has_abilities.expr.result-ast @@ -14,15 +14,15 @@ Defs( ], regions: [ @0-7, - @24-44, - @61-81, - @103-110, - @139-146, - @167-174, - @201-208, - @235-242, - @251-271, - @305-312, + @31-62, + @86-117, + @146-153, + @189-196, + @224-231, + @265-272, + @306-313, + @329-360, + @401-408, ], space_before: [ Slice(start = 0, length = 0), @@ -80,18 +80,18 @@ Defs( [], ), derived: Some( - @12-22 Has( + @19-29 Implements( [ - @13-15 HasAbility { - ability: @13-15 Apply( + @20-22 ImplementsAbility { + ability: @20-22 Apply( "", "Eq", [], ), impls: None, }, - @17-21 HasAbility { - ability: @17-21 Apply( + @24-28 ImplementsAbility { + ability: @24-28 Apply( "", "Hash", [], @@ -104,18 +104,18 @@ Defs( }, Opaque { header: TypeHeader { - name: @24-25 "A", + name: @31-32 "A", vars: [], }, - typ: @29-44 Where( - @29-30 BoundVariable( + typ: @36-62 Where( + @36-37 BoundVariable( "a", ), [ - @33-44 HasClause { - var: @33-34 "a", + @44-62 ImplementsClause { + var: @44-45 "a", abilities: [ - @39-44 Apply( + @57-62 Apply( "", "Other", [], @@ -125,18 +125,18 @@ Defs( ], ), derived: Some( - @49-59 Has( + @74-84 Implements( [ - @50-52 HasAbility { - ability: @50-52 Apply( + @75-77 ImplementsAbility { + ability: @75-77 Apply( "", "Eq", [], ), impls: None, }, - @54-58 HasAbility { - ability: @54-58 Apply( + @79-83 ImplementsAbility { + ability: @79-83 Apply( "", "Hash", [], @@ -149,18 +149,18 @@ Defs( }, Opaque { header: TypeHeader { - name: @61-62 "A", + name: @86-87 "A", vars: [], }, - typ: @66-81 Where( - @66-67 BoundVariable( + typ: @91-117 Where( + @91-92 BoundVariable( "a", ), [ - @70-81 HasClause { - var: @70-71 "a", + @99-117 ImplementsClause { + var: @99-100 "a", abilities: [ - @76-81 Apply( + @112-117 Apply( "", "Other", [], @@ -170,19 +170,19 @@ Defs( ], ), derived: Some( - @91-101 SpaceBefore( - Has( + @134-144 SpaceBefore( + Implements( [ - @92-94 HasAbility { - ability: @92-94 Apply( + @135-137 ImplementsAbility { + ability: @135-137 Apply( "", "Eq", [], ), impls: None, }, - @96-100 HasAbility { - ability: @96-100 Apply( + @139-143 ImplementsAbility { + ability: @139-143 Apply( "", "Hash", [], @@ -199,44 +199,44 @@ Defs( }, Opaque { header: TypeHeader { - name: @103-104 "A", + name: @146-147 "A", vars: [], }, - typ: @108-110 Apply( + typ: @151-153 Apply( "", "U8", [], ), derived: Some( - @115-137 Has( + @165-187 Implements( [ - @116-123 HasAbility { - ability: @116-118 Apply( + @166-173 ImplementsAbility { + ability: @166-168 Apply( "", "Eq", [], ), impls: Some( - @119-123 HasImpls( + @169-173 AbilityImpls( [ - @120-122 LabelOnly( - @120-122 "eq", + @170-172 LabelOnly( + @170-172 "eq", ), ], ), ), }, - @125-136 HasAbility { - ability: @125-129 Apply( + @175-186 ImplementsAbility { + ability: @175-179 Apply( "", "Hash", [], ), impls: Some( - @130-136 HasImpls( + @180-186 AbilityImpls( [ - @131-135 LabelOnly( - @131-135 "hash", + @181-185 LabelOnly( + @181-185 "hash", ), ], ), @@ -248,31 +248,31 @@ Defs( }, Opaque { header: TypeHeader { - name: @139-140 "A", + name: @189-190 "A", vars: [], }, - typ: @144-146 Apply( + typ: @194-196 Apply( "", "U8", [], ), derived: Some( - @151-165 Has( + @208-222 Implements( [ - @152-164 HasAbility { - ability: @152-154 Apply( + @209-221 ImplementsAbility { + ability: @209-211 Apply( "", "Eq", [], ), impls: Some( - @155-164 HasImpls( + @212-221 AbilityImpls( [ - @156-158 LabelOnly( - @156-158 "eq", + @213-215 LabelOnly( + @213-215 "eq", ), - @160-163 LabelOnly( - @160-163 "eq1", + @217-220 LabelOnly( + @217-220 "eq1", ), ], ), @@ -284,38 +284,38 @@ Defs( }, Opaque { header: TypeHeader { - name: @167-168 "A", + name: @224-225 "A", vars: [], }, - typ: @172-174 Apply( + typ: @229-231 Apply( "", "U8", [], ), derived: Some( - @179-199 Has( + @243-263 Implements( [ - @180-192 HasAbility { - ability: @180-182 Apply( + @244-256 ImplementsAbility { + ability: @244-246 Apply( "", "Eq", [], ), impls: Some( - @183-192 HasImpls( + @247-256 AbilityImpls( [ - @184-186 LabelOnly( - @184-186 "eq", + @248-250 LabelOnly( + @248-250 "eq", ), - @188-191 LabelOnly( - @188-191 "eq1", + @252-255 LabelOnly( + @252-255 "eq1", ), ], ), ), }, - @194-198 HasAbility { - ability: @194-198 Apply( + @258-262 ImplementsAbility { + ability: @258-262 Apply( "", "Hash", [], @@ -328,39 +328,39 @@ Defs( }, Opaque { header: TypeHeader { - name: @201-202 "A", + name: @265-266 "A", vars: [], }, - typ: @206-208 Apply( + typ: @270-272 Apply( "", "U8", [], ), derived: Some( - @213-233 Has( + @284-304 Implements( [ - @214-218 HasAbility { - ability: @214-218 Apply( + @285-289 ImplementsAbility { + ability: @285-289 Apply( "", "Hash", [], ), impls: None, }, - @220-232 HasAbility { - ability: @220-222 Apply( + @291-303 ImplementsAbility { + ability: @291-293 Apply( "", "Eq", [], ), impls: Some( - @223-232 HasImpls( + @294-303 AbilityImpls( [ - @224-226 LabelOnly( - @224-226 "eq", + @295-297 LabelOnly( + @295-297 "eq", ), - @228-231 LabelOnly( - @228-231 "eq1", + @299-302 LabelOnly( + @299-302 "eq1", ), ], ), @@ -372,34 +372,34 @@ Defs( }, Opaque { header: TypeHeader { - name: @235-236 "A", + name: @306-307 "A", vars: [], }, - typ: @240-242 Apply( + typ: @311-313 Apply( "", "U8", [], ), derived: Some( - @247-249 Has( + @325-327 Implements( [], ), ), }, Opaque { header: TypeHeader { - name: @251-252 "A", + name: @329-330 "A", vars: [], }, - typ: @256-271 Where( - @256-257 BoundVariable( + typ: @334-360 Where( + @334-335 BoundVariable( "a", ), [ - @260-271 HasClause { - var: @260-261 "a", + @342-360 ImplementsClause { + var: @342-343 "a", abilities: [ - @266-271 Apply( + @355-360 Apply( "", "Other", [], @@ -409,36 +409,36 @@ Defs( ], ), derived: Some( - @281-303 SpaceBefore( - Has( + @377-399 SpaceBefore( + Implements( [ - @282-289 HasAbility { - ability: @282-284 Apply( + @378-385 ImplementsAbility { + ability: @378-380 Apply( "", "Eq", [], ), impls: Some( - @285-289 HasImpls( + @381-385 AbilityImpls( [ - @286-288 LabelOnly( - @286-288 "eq", + @382-384 LabelOnly( + @382-384 "eq", ), ], ), ), }, - @291-302 HasAbility { - ability: @291-295 Apply( + @387-398 ImplementsAbility { + ability: @387-391 Apply( "", "Hash", [], ), impls: Some( - @296-302 HasImpls( + @392-398 AbilityImpls( [ - @297-301 LabelOnly( - @297-301 "hash", + @393-397 LabelOnly( + @393-397 "hash", ), ], ), @@ -454,25 +454,25 @@ Defs( }, Opaque { header: TypeHeader { - name: @305-306 "A", + name: @401-402 "A", vars: [], }, - typ: @310-312 Apply( + typ: @406-408 Apply( "", "U8", [], ), derived: Some( - @317-324 Has( + @420-427 Implements( [ - @318-323 HasAbility { - ability: @318-320 Apply( + @421-426 ImplementsAbility { + ability: @421-423 Apply( "", "Eq", [], ), impls: Some( - @321-323 HasImpls( + @424-426 AbilityImpls( [], ), ), @@ -484,7 +484,7 @@ Defs( ], value_defs: [], }, - @326-327 SpaceBefore( + @429-430 SpaceBefore( Num( "0", ), diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast index f06dab08717..02f717dfdf6 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_function.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(2147483648), ], regions: [ - @0-27, + @0-38, ], space_before: [ Slice(start = 0, length = 0), @@ -19,7 +19,7 @@ Defs( @0-1 Identifier( "f", ), - @4-27 Where( + @4-38 Where( @4-16 Function( [ @4-5 BoundVariable( @@ -38,10 +38,10 @@ Defs( ), ), [ - @20-27 HasClause { - var: @20-21 "a", + @24-38 ImplementsClause { + var: @24-25 "a", abilities: [ - @26-27 Apply( + @37-38 Apply( "", "A", [], @@ -53,7 +53,7 @@ Defs( ), ], }, - @29-30 SpaceBefore( + @40-41 SpaceBefore( Var { module_name: "", ident: "f", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast index c68f1217e9d..fd2cc424672 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_bound_abilities.expr.result-ast @@ -5,8 +5,8 @@ Defs( Index(2147483649), ], regions: [ - @0-55, - @57-118, + @0-73, + @75-154, ], space_before: [ Slice(start = 0, length = 0), @@ -26,7 +26,7 @@ Defs( @0-1 Identifier( "f", ), - @4-55 Where( + @4-73 Where( @4-10 Function( [ @4-5 BoundVariable( @@ -38,35 +38,35 @@ Defs( ), ), [ - @13-28 HasClause { - var: @13-14 "a", + @17-39 ImplementsClause { + var: @17-18 "a", abilities: [ - @19-23 Apply( + @30-34 Apply( "", "Hash", [], ), - @26-28 Apply( + @37-39 Apply( "", "Eq", [], ), ], }, - @30-55 HasClause { - var: @30-31 "b", + @41-73 ImplementsClause { + var: @41-42 "b", abilities: [ - @36-38 Apply( + @54-56 Apply( "", "Eq", [], ), - @41-45 Apply( + @59-63 Apply( "", "Hash", [], ), - @48-55 Apply( + @66-73 Apply( "", "Display", [], @@ -77,18 +77,18 @@ Defs( ), ), Annotation( - @57-58 Identifier( + @75-76 Identifier( "f", ), - @61-118 Where( - @61-67 SpaceAfter( + @79-154 Where( + @79-85 SpaceAfter( Function( [ - @61-62 BoundVariable( + @79-80 BoundVariable( "a", ), ], - @66-67 BoundVariable( + @84-85 BoundVariable( "b", ), ), @@ -97,40 +97,40 @@ Defs( ], ), [ - @72-87 HasClause { - var: @72-73 "a", + @94-116 ImplementsClause { + var: @94-95 "a", abilities: [ - @78-82 Apply( + @107-111 Apply( "", "Hash", [], ), - @85-87 Apply( + @114-116 Apply( "", "Eq", [], ), ], }, - @93-118 HasClause { - var: @93-94 SpaceBefore( + @122-154 ImplementsClause { + var: @122-123 SpaceBefore( "b", [ Newline, ], ), abilities: [ - @99-103 Apply( + @135-139 Apply( "", "Hash", [], ), - @106-113 Apply( + @142-149 Apply( "", "Display", [], ), - @116-118 Apply( + @152-154 Apply( "", "Eq", [], @@ -142,7 +142,7 @@ Defs( ), ], }, - @120-121 SpaceBefore( + @156-157 SpaceBefore( Var { module_name: "", ident: "f", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast index 05f6b2b66dc..e252c64ff9d 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(2147483648), ], regions: [ - @0-48, + @0-73, ], space_before: [ Slice(start = 0, length = 0), @@ -19,7 +19,7 @@ Defs( @0-1 Identifier( "f", ), - @4-48 Where( + @4-73 Where( @4-16 Function( [ @4-5 BoundVariable( @@ -38,30 +38,30 @@ Defs( ), ), [ - @20-27 HasClause { - var: @20-21 "a", + @24-38 ImplementsClause { + var: @24-25 "a", abilities: [ - @26-27 Apply( + @37-38 Apply( "", "A", [], ), ], }, - @29-37 HasClause { - var: @29-30 "b", + @40-55 ImplementsClause { + var: @40-41 "b", abilities: [ - @35-37 Apply( + @53-55 Apply( "", "Eq", [], ), ], }, - @39-48 HasClause { - var: @39-40 "c", + @57-73 ImplementsClause { + var: @57-58 "c", abilities: [ - @45-48 Apply( + @70-73 Apply( "", "Ord", [], @@ -73,7 +73,7 @@ Defs( ), ], }, - @50-51 SpaceBefore( + @75-76 SpaceBefore( Var { module_name: "", ident: "f", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc index d5d6c87616e..9076cc336ad 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.formatted.roc @@ -1,3 +1,3 @@ -f : a -> (b -> c) where a implements Hash, b has Eq, c implements Ord +f : a -> (b -> c) where a implements Hash, b implements Eq, c implements Ord f \ No newline at end of file diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast index 8ea27a6af78..d29d1e2569f 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_multiple_has_across_newlines.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(2147483648), ], regions: [ - @0-67, + @0-92, ], space_before: [ Slice(start = 0, length = 0), @@ -19,7 +19,7 @@ Defs( @0-1 Identifier( "f", ), - @4-67 Where( + @4-92 Where( @4-16 SpaceAfter( Function( [ @@ -43,40 +43,40 @@ Defs( ], ), [ - @24-34 HasClause { - var: @24-25 "a", + @28-45 ImplementsClause { + var: @28-29 "a", abilities: [ - @30-34 Apply( + @41-45 Apply( "", "Hash", [], ), ], }, - @42-50 HasClause { - var: @42-43 SpaceBefore( + @53-68 ImplementsClause { + var: @53-54 SpaceBefore( "b", [ Newline, ], ), abilities: [ - @48-50 Apply( + @66-68 Apply( "", "Eq", [], ), ], }, - @58-67 HasClause { - var: @58-59 SpaceBefore( + @76-92 ImplementsClause { + var: @76-77 SpaceBefore( "c", [ Newline, ], ), abilities: [ - @64-67 Apply( + @89-92 Apply( "", "Ord", [], @@ -88,7 +88,7 @@ Defs( ), ], }, - @69-70 SpaceBefore( + @94-95 SpaceBefore( Var { module_name: "", ident: "f", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast index 862b258bf81..30486cee678 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_non_function.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(2147483648), ], regions: [ - @0-15, + @0-26, ], space_before: [ Slice(start = 0, length = 0), @@ -19,15 +19,15 @@ Defs( @0-1 Identifier( "f", ), - @4-15 Where( + @4-26 Where( @4-5 BoundVariable( "a", ), [ - @8-15 HasClause { - var: @8-9 "a", + @12-26 ImplementsClause { + var: @12-13 "a", abilities: [ - @14-15 Apply( + @25-26 Apply( "", "A", [], @@ -39,7 +39,7 @@ Defs( ), ], }, - @17-18 SpaceBefore( + @28-29 SpaceBefore( Var { module_name: "", ident: "f", diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast index ad552875edc..ca97aea704c 100644 --- a/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast +++ b/crates/compiler/test_syntax/tests/snapshots/pass/where_clause_on_newline.expr.result-ast @@ -4,7 +4,7 @@ Defs( Index(2147483648), ], regions: [ - @0-29, + @0-40, ], space_before: [ Slice(start = 0, length = 0), @@ -19,7 +19,7 @@ Defs( @0-1 Identifier( "f", ), - @4-29 Where( + @4-40 Where( @4-12 SpaceAfter( Function( [ @@ -38,10 +38,10 @@ Defs( ], ), [ - @19-29 HasClause { - var: @19-20 "a", + @23-40 ImplementsClause { + var: @23-24 "a", abilities: [ - @25-29 Apply( + @36-40 Apply( "", "Hash", [], @@ -53,7 +53,7 @@ Defs( ), ], }, - @31-32 SpaceBefore( + @42-43 SpaceBefore( Var { module_name: "", ident: "f", From 79086458950894ef84dc8e53ce782c114a35ed07 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 22:24:24 -0400 Subject: [PATCH 52/55] Fix more tests --- .../compiler/uitest/tests/ability/smoke/decoder.txt | 4 ++-- .../compiler/uitest/tests/ability/smoke/encoder.txt | 4 ++-- .../uitest/tests/ability/specialize/dec_hash.txt | 2 +- .../polymorphic_lambda_set_specialization.txt | 4 ++-- ...orphic_lambda_set_specialization_bound_output.txt | 4 ++-- ...specialization_branching_over_single_variable.txt | 4 ++-- ...pecialization_varying_over_multiple_variables.txt | 12 ++++++------ ...n_varying_over_multiple_variables_two_results.txt | 12 ++++++------ ...lization_with_deep_specialization_and_capture.txt | 4 ++-- ...c_lambda_set_specialization_with_let_weakened.txt | 4 ++-- ...et_specialization_with_let_weakened_unapplied.txt | 4 ++-- .../specialize/resolve_lambda_set_ability_chain.txt | 4 ++-- ...ve_lambda_set_branches_ability_vs_non_ability.txt | 2 +- .../resolve_lambda_set_branches_same_ability.txt | 2 +- .../resolve_lambda_set_generalized_ability_alias.txt | 2 +- .../resolve_lambda_set_weakened_ability_alias.txt | 2 +- ...esolve_mutually_recursive_ability_lambda_sets.txt | 2 +- ...tually_recursive_ability_lambda_sets_inferred.txt | 2 +- .../resolve_recursive_ability_lambda_set.txt | 2 +- ...o_unspecialized_lambda_sets_in_one_lambda_set.txt | 2 +- ...resolve_unspecialized_lambda_set_behind_alias.txt | 2 +- ...esolve_unspecialized_lambda_set_behind_opaque.txt | 2 +- .../ability/specialize/static_specialization.txt | 2 +- .../instantiate/call_generic_ability_member.txt | 2 +- 24 files changed, 43 insertions(+), 43 deletions(-) diff --git a/crates/compiler/uitest/tests/ability/smoke/decoder.txt b/crates/compiler/uitest/tests/ability/smoke/decoder.txt index 1ceffa6ecc3..085d98c4931 100644 --- a/crates/compiler/uitest/tests/ability/smoke/decoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/decoder.txt @@ -4,10 +4,10 @@ MDecodeError : [TooShort, Leftover (List U8)] MDecoder val fmt := List U8, fmt -> { result: Result val MDecodeError, rest: List U8 } where fmt implements MDecoderFormatting -MDecoding has +MDecoding implements decoder : MDecoder val fmt where val implements MDecoding, fmt implements MDecoderFormatting -MDecoderFormatting has +MDecoderFormatting implements u8 : MDecoder U8 fmt where fmt implements MDecoderFormatting decodeWith : List U8, MDecoder val fmt, fmt -> { result: Result val MDecodeError, rest: List U8 } where fmt implements MDecoderFormatting diff --git a/crates/compiler/uitest/tests/ability/smoke/encoder.txt b/crates/compiler/uitest/tests/ability/smoke/encoder.txt index 88dee647b49..12f639bf021 100644 --- a/crates/compiler/uitest/tests/ability/smoke/encoder.txt +++ b/crates/compiler/uitest/tests/ability/smoke/encoder.txt @@ -2,10 +2,10 @@ app "test" provides [myU8Bytes] to "./platform" MEncoder fmt := List U8, fmt -> List U8 where fmt implements Format -MEncoding has +MEncoding implements toEncoder : val -> MEncoder fmt where val implements MEncoding, fmt implements Format -Format has +Format implements u8 : U8 -> MEncoder fmt where fmt implements Format appendWith : List U8, MEncoder fmt, fmt -> List U8 where fmt implements Format diff --git a/crates/compiler/uitest/tests/ability/specialize/dec_hash.txt b/crates/compiler/uitest/tests/ability/specialize/dec_hash.txt index facc13c6ae4..a69b5c6722e 100644 --- a/crates/compiler/uitest/tests/ability/specialize/dec_hash.txt +++ b/crates/compiler/uitest/tests/ability/specialize/dec_hash.txt @@ -2,4 +2,4 @@ app "test" provides [main] to "./platform" main = \h -> Hash.hash h 1.1dec - # ^^^^^^^^^ Hash#Hash.hash(1): a, Dec -[[Hash.hashDec(17)]]-> a | a has Hasher + # ^^^^^^^^^ Hash#Hash.hash(1): a, Dec -[[Hash.hashDec(17)]]-> a where a implements Hasher diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt index 09856a4f4c3..a9b7ba5ceb7 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) where a implements F, b implements G -G has g : b -> {} where b implements G +F implements f : a -> (b -> {}) where a implements F, b implements G +G implements g : b -> {} where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt index 7cf1ab95b89..fcedaca3cf4 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_bound_output.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -F has f : a -> ({} -> b) where a implements F, b implements G -G has g : {} -> b where b implements G +F implements f : a -> ({} -> b) where a implements F, b implements G +G implements g : {} -> b where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt index fd4340d36ab..abc75f0c2ec 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_branching_over_single_variable.txt @@ -1,7 +1,7 @@ app "test" provides [f] to "./platform" -J has j : j -> (k -> {}) where j implements J, k implements K -K has k : k -> {} where k implements K +J implements j : j -> (k -> {}) where j implements J, k implements K +K implements k : k -> {} where k implements K C := {} implements [J {j: jC}] jC = \@C _ -> k diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt index 907ffcb1e14..1d3192d5325 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) where j implements J, k implements K -K has k : k -> {} where k implements K +J implements j : j -> (k -> {}) where j implements J, k implements K +K implements k : k -> {} where k implements K C := {} implements [J {j: jC}] jC = \@C _ -> k @@ -19,14 +19,14 @@ f = \flag, a, b -> # ^ j where j implements J # ^ j where j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 implements J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) where j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) where j implements J, j1 implements J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) where j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) where j implements J, j1 implements J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 implements J, k implements K main = (f A (@C {}) (@D {})) (@E {}) # ^ [A, B], C, D -[[f(11)]]-> (E -[[k(10)]]-> {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt index 27f1f4b11dd..5cf0feadae4 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_varying_over_multiple_variables_two_results.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -J has j : j -> (k -> {}) where j implements J, k implements K -K has k : k -> {} where k implements K +J implements j : j -> (k -> {}) where j implements J, k implements K +K implements k : k -> {} where k implements K C := {} implements [J {j: jC}] jC = \@C _ -> k @@ -23,14 +23,14 @@ f = \flag, a, b -> # ^ j where j implements J # ^ j where j implements J it = -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 implements J, k implements K when flag is A -> j a - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) where j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j:j(2):2 + j1:j(2):2]-> {}) where j implements J, j1 implements J, k implements K B -> j b - # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) where j implements J, j1 has J, k implements K + # ^ J#j(2): j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) where j implements J, j1 implements J, k implements K it -# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 has J, k implements K +# ^^ k -[[] + j:j(2):2 + j1:j(2):2]-> {} where j implements J, j1 implements J, k implements K main = #^^^^{-1} {} diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt index 57331a3945a..3040768282c 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_deep_specialization_and_capture.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -F has f : a, b -> ({} -> ({} -> {})) where a implements F, b implements G -G has g : b -> ({} -> {}) where b implements G +F implements f : a, b -> ({} -> ({} -> {})) where a implements F, b implements G +G implements g : b -> ({} -> {}) where b implements G Fo := {} implements [F {f}] f = \@Fo {}, b -> \{} -> g b diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt index 56dd2e74789..d52dd502324 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) where a implements F, b implements G -G has g : b -> {} where b implements G +F implements f : a -> (b -> {}) where a implements F, b implements G +G implements g : b -> {} where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g diff --git a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt index 4cdda675096..6a0e2b3e98f 100644 --- a/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt +++ b/crates/compiler/uitest/tests/ability/specialize/polymorphic_lambda_set_specialization_with_let_weakened_unapplied.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -F has f : a -> (b -> {}) where a implements F, b implements G -G has g : b -> {} where b implements G +F implements f : a -> (b -> {}) where a implements F, b implements G +G implements g : b -> {} where b implements G Fo := {} implements [F {f}] f = \@Fo {} -> g diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt index 6903975585a..23705beb8ec 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_ability_chain.txt @@ -1,7 +1,7 @@ app "test" provides [main] to "./platform" -Id1 has id1 : a -> a where a implements Id1 -Id2 has id2 : a -> a where a implements Id2 +Id1 implements id1 : a -> a where a implements Id1 +Id2 implements id2 : a -> a where a implements Id2 A := {} implements [Id1 {id1}, Id2 {id2}] id1 = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt index 56fb6b5fed3..d7c226d7d24 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_ability_vs_non_ability.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a where a implements Id +Id implements id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt index 744dc8ed30d..ecaef311f1c 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_branches_same_ability.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a where a implements Id +Id implements id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt index 76b859f1dea..90a6ab84fe0 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_generalized_ability_alias.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a where a implements Id +Id implements id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt index 6304b2434db..e90cf3ebae5 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_lambda_set_weakened_ability_alias.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Id has id : a -> a where a implements Id +Id implements id : a -> a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt index 3c6fdc4f492..3daf251c372 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Bounce has +Bounce implements ping : a -> a where a implements Bounce pong : a -> a where a implements Bounce diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt index 43a739a59a6..560ead417ce 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_mutually_recursive_ability_lambda_sets_inferred.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Bounce has +Bounce implements ping : a -> a where a implements Bounce pong : a -> a where a implements Bounce diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt index a6373f7eafc..993454a1b6b 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_recursive_ability_lambda_set.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Diverge has diverge : a -> a where a implements Diverge +Diverge implements diverge : a -> a where a implements Diverge A := {} implements [Diverge {diverge}] diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt index 8b572588f3e..3d6991faa9e 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_two_unspecialized_lambda_sets_in_one_lambda_set.txt @@ -3,7 +3,7 @@ app "test" provides [main] to "./platform" Thunk a : {} -> a -Id has id : a -> Thunk a where a implements Id +Id implements id : a -> Thunk a where a implements Id A := {} implements [Id {id}] id = \@A {} -> \{} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt index 5431c48b1a8..e8056b83409 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_alias.txt @@ -3,7 +3,7 @@ app "test" provides [main] to "./platform" Thunk a : {} -> a -Id has id : a -> Thunk a where a implements Id +Id implements id : a -> Thunk a where a implements Id A := {} implements [Id {id}] id = \@A {} -> \{} -> @A {} diff --git a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt index 25352cdabf7..aa7ff8e6a7a 100644 --- a/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt +++ b/crates/compiler/uitest/tests/ability/specialize/resolve_unspecialized_lambda_set_behind_opaque.txt @@ -3,7 +3,7 @@ app "test" provides [main] to "./platform" Thunk a := {} -> a -Id has id : a -> Thunk a where a implements Id +Id implements id : a -> Thunk a where a implements Id A := {} implements [Id {id}] id = \@A {} -> @Thunk (\{} -> @A {}) diff --git a/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt b/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt index 01dadc8d6f8..ab53585cf39 100644 --- a/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt +++ b/crates/compiler/uitest/tests/ability/specialize/static_specialization.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -Default has default : {} -> a where a implements Default +Default implements default : {} -> a where a implements Default A := {} implements [Default {default}] default = \{} -> @A {} diff --git a/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt b/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt index 6e99d30a577..e1cdbcce81f 100644 --- a/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt +++ b/crates/compiler/uitest/tests/instantiate/call_generic_ability_member.txt @@ -1,6 +1,6 @@ app "test" provides [main] to "./platform" -X has +X implements consume : a -> {} where a implements X O := {} implements [X {consume: consumeO}] From 2ca3c420a322de7b9673577967fcbe07dfcd0cb6 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 23:04:02 -0400 Subject: [PATCH 53/55] Delete some trailing spaces --- www/build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/www/build.sh b/www/build.sh index a5581ce0693..ff1b92f33d9 100755 --- a/www/build.sh +++ b/www/build.sh @@ -23,7 +23,7 @@ DESIGN_ASSETS_COMMIT="4d949642ebc56ca455cf270b288382788bce5873" DESIGN_ASSETS_TARFILE="roc-lang-design-assets-4d94964.tar.gz" DESIGN_ASSETS_DIR="roc-lang-design-assets-4d94964" -curl -fLJO https://github.com/roc-lang/design-assets/tarball/$DESIGN_ASSETS_COMMIT +curl -fLJO https://github.com/roc-lang/design-assets/tarball/$DESIGN_ASSETS_COMMIT tar -xzf $DESIGN_ASSETS_TARFILE mv $DESIGN_ASSETS_DIR/fonts build/ rm -rf $DESIGN_ASSETS_TARFILE $DESIGN_ASSETS_DIR @@ -71,7 +71,7 @@ if ! [ -v GITHUB_TOKEN_READ_ONLY ]; then roc=target/release/roc else echo 'Fetching latest roc nightly...' - + # get roc release archive curl -fOL https://github.com/roc-lang/roc/releases/download/nightly/roc_nightly-linux_x86_64-latest.tar.gz # extract archive @@ -124,7 +124,7 @@ if [ -v GITHUB_TOKEN_READ_ONLY ]; then curl -v -H "Authorization: $GITHUB_TOKEN_READ_ONLY" -fL -o basic_cli_releases.json "https://api.github.com/repos/roc-lang/basic-cli/releases" DOCS_LINKS=$(cat basic_cli_releases.json | jq -r '.[] | .assets[] | select(.name=="docs.tar.gz") | .browser_download_url') - + rm basic_cli_releases.json VERSION_NUMBERS=$(echo "$DOCS_LINKS" | grep -oP '(?<=/download/)[^/]+(?=/docs.tar.gz)') From 254226f0674e60c78f1f1e2f807c3818c7790979 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 10 Aug 2023 23:04:10 -0400 Subject: [PATCH 54/55] Use abilities-syntax branch of basic-cli for now --- www/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/build.sh b/www/build.sh index ff1b92f33d9..79ed5d67e6a 100755 --- a/www/build.sh +++ b/www/build.sh @@ -107,7 +107,7 @@ export ROC_DOCS_URL_ROOT=/packages/basic-cli rm -rf ./downloaded-basic-cli -git clone --depth 1 https://github.com/roc-lang/basic-cli.git downloaded-basic-cli +git clone --branch new-abilities-syntax --depth 1 https://github.com/roc-lang/basic-cli.git downloaded-basic-cli cargo run --bin roc-docs downloaded-basic-cli/src/main.roc From 954f68766621df016c0cf5d220be579c350fe19c Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:14:33 +0200 Subject: [PATCH 55/55] minor fixes --- crates/compiler/parse/src/expr.rs | 2 +- crates/compiler/parse/src/parser.rs | 2 +- crates/compiler/parse/src/type_annotation.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 31bbc892908..ed216452e37 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -1286,7 +1286,7 @@ mod ability { Exact(u32), } - /// Parses an ability demand like `hash : a -> U64 | a implements Hash`, in the context of a larger + /// Parses an ability demand like `hash : a -> U64 where a implements Hash`, in the context of a larger /// ability definition. /// This is basically the same as parsing a free-floating annotation, but with stricter rules. pub fn parse_demand<'a>( diff --git a/crates/compiler/parse/src/parser.rs b/crates/compiler/parse/src/parser.rs index 26048884176..1caef428676 100644 --- a/crates/compiler/parse/src/parser.rs +++ b/crates/compiler/parse/src/parser.rs @@ -599,7 +599,7 @@ pub enum EType<'a> { TEnd(Position), TFunctionArgument(Position), TWhereBar(Position), - THasClause(Position), + TImplementsClause(Position), TAbilityImpl(ETypeAbilityImpl<'a>, Position), /// TIndentStart(Position), diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index 6f33073a66a..7f5d85205b8 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -426,7 +426,7 @@ fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc>>, ETyp EType::TIndentEnd, ), zero_or_more!(skip_first!( - word1(b'&', EType::THasClause), + word1(b'&', EType::TImplementsClause), space0_before_optional_after( specialize(EType::TApply, loc!(concrete_type())), EType::TIndentStart, @@ -459,7 +459,7 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc>, EType<' ), skip_first!( // Parse "implements"; we don't care about this keyword - word(crate::keyword::IMPLEMENTS, EType::THasClause), + word(crate::keyword::IMPLEMENTS, EType::TImplementsClause), // Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash" absolute_column_min_indent(ability_chain()) ) @@ -494,7 +494,7 @@ fn implements_clause_chain<'a>( let (_, first_clause, state) = implements_clause().parse(arena, state, min_indent)?; let (_, mut clauses, state) = zero_or_more!(skip_first!( - word1(b',', EType::THasClause), + word1(b',', EType::TImplementsClause), implements_clause() )) .parse(arena, state, min_indent)?; @@ -514,7 +514,7 @@ fn implements_clause_chain<'a>( pub fn implements_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> { increment_min_indent(skip_first!( // Parse "implements"; we don't care about this keyword - word(crate::keyword::IMPLEMENTS, EType::THasClause), + word(crate::keyword::IMPLEMENTS, EType::TImplementsClause), // Parse "Hash"; this may be qualified from another module like "Hash.Hash" space0_before_e( loc!(map!(