diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index 464ad0cf27..6b01cffbf2 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -1530,6 +1530,13 @@ fn canonicalize_var_lookup( output.references.insert_value_lookup(symbol); if scope.abilities_store.is_ability_member_name(symbol) { + // Is there a shadow implementation with the same name? If so, we might be in + // the def for that shadow. In that case add a value lookup of the shadow impl, + // so that it's marked as possibly-recursive. + if let Some(shadow) = scope.get_member_shadow(symbol) { + output.references.insert_value_lookup(shadow.value); + } + AbilityMember( symbol, Some(scope.abilities_store.fresh_specialization_id()), diff --git a/crates/compiler/can/src/pattern.rs b/crates/compiler/can/src/pattern.rs index eda874f534..1ebfb7db7e 100644 --- a/crates/compiler/can/src/pattern.rs +++ b/crates/compiler/can/src/pattern.rs @@ -205,6 +205,7 @@ pub fn canonicalize_def_header_pattern<'a>( } // Likely a specialization of an ability. Some(ability_member_name) => { + output.references.insert_bound(symbol); output.references.insert_value_lookup(ability_member_name); Pattern::AbilityMemberSpecialization { ident: symbol, diff --git a/crates/compiler/can/src/scope.rs b/crates/compiler/can/src/scope.rs index 8c12815c94..54fda6ae11 100644 --- a/crates/compiler/can/src/scope.rs +++ b/crates/compiler/can/src/scope.rs @@ -348,6 +348,10 @@ impl Scope { } } + pub fn get_member_shadow(&self, ability_member: Symbol) -> Option<&Loc> { + self.shadows.get(&ability_member) + } + /// Create a new symbol, but don't add it to the scope (yet) /// /// Used for record guards like { x: Just _ } where the `x` is not added to the scope, diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 773c77b36b..cf33d36bad 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -6792,6 +6792,8 @@ mod solve_expr { Diverge has diverge : a -> a | a has Diverge A := {} has [Diverge {diverge}] + + diverge : A -> A diverge = \@A {} -> diverge (@A {}) #^^^^^^^{-1} ^^^^^^^ @@ -6805,7 +6807,7 @@ mod solve_expr { ), @r###" A#diverge(4) : A -[[diverge(4)]]-> A - Diverge#diverge(2) : A -[[diverge(4)]]-> A + A#diverge(4) : A -[[diverge(4)]]-> A A#diverge(4) : A -[[diverge(4)]]-> A "### ) @@ -6824,9 +6826,11 @@ mod solve_expr { A := {} has [Bounce {ping, pong}] + ping : A -> A ping = \@A {} -> pong (@A {}) #^^^^{-1} ^^^^ + pong : A -> A pong = \@A {} -> ping (@A {}) #^^^^{-1} ^^^^ @@ -6840,7 +6844,7 @@ mod solve_expr { ), @r###" A#ping(5) : A -[[ping(5)]]-> A - Bounce#pong(3) : A -[[pong(6)]]-> A + A#pong(6) : A -[[pong(6)]]-> A A#pong(6) : A -[[pong(6)]]-> A A#ping(5) : A -[[ping(5)]]-> A A#ping(5) : A -[[ping(5)]]-> A