mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
abilities syntax has
-> implements
This commit is contained in:
parent
91e37293a2
commit
dbc0204532
21 changed files with 89 additions and 84 deletions
|
@ -80,7 +80,7 @@ impl AbilityMemberData<Resolved> {
|
|||
|
||||
/// Solved lambda sets for an ability member specialization. For example, if we have
|
||||
///
|
||||
/// Default has default : {} -[[] + a:default:1]-> a | a has Default
|
||||
/// Default has default : {} -[[] + a:default:1]-> a | a implements Default
|
||||
///
|
||||
/// A := {}
|
||||
/// default = \{} -[[closA]]-> @A {}
|
||||
|
@ -144,7 +144,7 @@ pub struct IAbilitiesStore<Phase: ResolvePhase> {
|
|||
///
|
||||
/// For example, in the program
|
||||
///
|
||||
/// Hash has hash : a -> U64 | a has Hash
|
||||
/// Hash has hash : a -> U64 | a implements Hash
|
||||
///
|
||||
/// Id := {} implements [Hash {hash: myHash}]
|
||||
/// myHash = \@Id n -> n
|
||||
|
@ -284,7 +284,7 @@ impl<Phase: ResolvePhase> IAbilitiesStore<Phase> {
|
|||
}
|
||||
|
||||
/// Finds the implementation key for a symbol specializing the ability member, if it specializes any.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a has Hash`.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a implements Hash`.
|
||||
/// Calling this with `hashId` would retrieve (hash, hashId).
|
||||
pub fn impl_key(&self, specializing_symbol: Symbol) -> Option<&ImplKey> {
|
||||
self.specialization_to_root.get(&specializing_symbol)
|
||||
|
@ -392,7 +392,7 @@ pub enum MarkError {
|
|||
impl IAbilitiesStore<Resolved> {
|
||||
/// Finds the symbol name and ability member definition for a symbol specializing the ability
|
||||
/// member, if it specializes any.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a has Hash`.
|
||||
/// For example, suppose `hashId : Id -> U64` specializes `hash : a -> U64 | a implements Hash`.
|
||||
/// Calling this with `hashId` would retrieve the ability member data for `hash`, and what type
|
||||
/// `hashId` is specializing for.
|
||||
pub fn impl_key_and_def(
|
||||
|
|
|
@ -296,7 +296,7 @@ pub(crate) fn canonicalize_annotation(
|
|||
|
||||
let (annotation, region) = match annotation {
|
||||
TypeAnnotation::Where(annotation, clauses) => {
|
||||
// Add each "has" clause. The association of a variable to an ability will be saved on
|
||||
// Add each "implements" clause. The association of a variable to an ability will be saved on
|
||||
// `introduced_variables`, which we'll process later.
|
||||
for clause in clauses.iter() {
|
||||
let opt_err = canonicalize_has_clause(
|
||||
|
|
|
@ -480,7 +480,7 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
//
|
||||
// interface F imports [] exposes []
|
||||
//
|
||||
// Hello := {} has [Encoding.{ toEncoder }]
|
||||
// Hello := {} implements [Encoding.{ toEncoder }]
|
||||
//
|
||||
// toEncoder = \@Hello {} -> ...
|
||||
//
|
||||
|
@ -492,7 +492,7 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
//
|
||||
// interface F imports [Encoding.{ toEncoder }] exposes []
|
||||
//
|
||||
// Hello := {} has [Encoding.{ toEncoder }]
|
||||
// Hello := {} implements [Encoding.{ toEncoder }]
|
||||
//
|
||||
// toEncoder = \@Hello {} -> ...
|
||||
//
|
||||
|
@ -510,9 +510,9 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
// definition symbol, for example when the ability is defined in the same
|
||||
// module as an implementer:
|
||||
//
|
||||
// Eq has eq : a, a -> U64 | a has Eq
|
||||
// Eq has eq : a, a -> U64 | a implements Eq
|
||||
//
|
||||
// A := U8 has [Eq {eq}]
|
||||
// A := U8 implements [Eq {eq}]
|
||||
//
|
||||
// So, do a final check that the implementation symbol is not resolved directly
|
||||
// to the member.
|
||||
|
@ -749,8 +749,8 @@ fn canonicalize_opaque<'a>(
|
|||
// Did the user claim this implementation for a specialization of a different
|
||||
// type? e.g.
|
||||
//
|
||||
// A has [Hash {hash: myHash}]
|
||||
// B has [Hash {hash: myHash}]
|
||||
// A implements [Hash {hash: myHash}]
|
||||
// B implements [Hash {hash: myHash}]
|
||||
//
|
||||
// If so, that's an error and we drop the impl for this opaque type.
|
||||
let member_impl = match scope.abilities_store.impl_key(impl_symbol) {
|
||||
|
@ -1398,7 +1398,7 @@ fn resolve_abilities(
|
|||
}
|
||||
[..] => {
|
||||
// There is more than one variable bound to the member signature, so something like
|
||||
// Eq has eq : a, b -> Bool | a has Eq, b has Eq
|
||||
// Eq has eq : a, b -> Bool | a has Eq, b implements Eq
|
||||
// We have no way of telling what type implements a particular instance of Eq in
|
||||
// this case (a or b?), so disallow it.
|
||||
let span_has_clauses = Region::across_all(
|
||||
|
|
|
@ -76,7 +76,7 @@ pub enum Pattern {
|
|||
Underscore,
|
||||
|
||||
/// An identifier that marks a specialization of an ability member.
|
||||
/// For example, given an ability member definition `hash : a -> U64 | a has Hash`,
|
||||
/// For example, given an ability member definition `hash : a -> U64 | a implements Hash`,
|
||||
/// there may be the specialization `hash : Bool -> U64`. In this case we generate a
|
||||
/// new symbol for the specialized "hash" identifier.
|
||||
AbilityMemberSpecialization {
|
||||
|
|
|
@ -33,7 +33,7 @@ pub struct Scope {
|
|||
imports: Vec<(Ident, Symbol, Region)>,
|
||||
|
||||
/// Shadows of an ability member, for example a local specialization of `eq` for the ability
|
||||
/// member `Eq has eq : a, a -> Bool | a has Eq` gets a shadow symbol it can use for its
|
||||
/// member `Eq has eq : a, a -> Bool | a implements Eq` gets a shadow symbol it can use for its
|
||||
/// implementation.
|
||||
///
|
||||
/// Only one shadow of an ability member is permitted per scope.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue