Skip to content

Commit

Permalink
beef up transcript and fix a couple bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellwrosen committed Aug 12, 2024
1 parent 84b45c6 commit 25aeacd
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 34 deletions.
48 changes: 28 additions & 20 deletions unison-core/src/Unison/Type/Names.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,21 @@ bindNames unsafeVarToName nameToVar localVars namespaceNames ty =
--
-- type Foo.Bar = ...
-- type Baz.Qux = ...
-- type Whatever =
-- Whatever
-- Foo.Bar -- this variable is *not* unresolved: it matches locally-bound `Foo.Bar` exactly
-- Qux -- this variable *is* unresolved: it doesn't match any locally-bound type exactly
-- type Whatever = Whatever Foo.Bar Qux
-- ^^^^^^^ ^^^
-- | this variable *is* unresolved: it doesn't match any locally-bound type exactly
-- |
-- this variable is *not* unresolved: it matches locally-bound `Foo.Bar` exactly
unresolvedVars :: [(v, a)]
unresolvedVars =
ABT.freeVarOccurrences localVars ty

-- For each unresolved variable, look up what it might refer to in two places:
-- For each unresolved variable, look up what it might refer to:
--
-- 1. The names from the namespace, less all of the local names (because exact matches shadow the namespace)
-- 2. The local names.
resolvedVars :: [(v, a, Set TypeReference, Set Name)]
-- 1. An exact match in the namespace.
-- 2. A suffix match in the namespace.
-- 3. A suffix match in the local names..
resolvedVars :: [(v, a, (Set TypeReference, Set TypeReference), Set Name)]
resolvedVars =
map
( \(v, a) ->
Expand All @@ -62,13 +64,17 @@ bindNames unsafeVarToName nameToVar localVars namespaceNames ty =
)
unresolvedVars

checkAmbiguity :: (v, a, Set TypeReference, Set Name) -> Either (Seq (Names.ResolutionFailure v a)) (v, ResolvesTo)
checkAmbiguity (v, a, namespaceMatches, localMatches) =
case (Set.size namespaceMatches, Set.size localMatches) of
(0, 0) -> bad Names.NotFound
(1, 0) -> good (ResolvesToNamespace (Set.findMin namespaceMatches))
(0, 1) -> good (ResolvesToLocal (Set.findMin localMatches))
_ -> bad (Names.Ambiguous namespaceNames namespaceMatches localMatches)
checkAmbiguity ::
(v, a, (Set TypeReference, Set TypeReference), Set Name) ->
Either (Seq (Names.ResolutionFailure v a)) (v, ResolvesTo)
checkAmbiguity (v, a, (exactNamespaceMatches, suffixNamespaceMatches), localMatches) =
case (Set.size exactNamespaceMatches, Set.size suffixNamespaceMatches, Set.size localMatches) of
(1, _, _) -> good (ResolvesToNamespace (Set.findMin exactNamespaceMatches))
(n, _, _) | n > 1 -> bad (Names.Ambiguous namespaceNames exactNamespaceMatches Set.empty)
(_, 0, 0) -> bad Names.NotFound
(_, 1, 0) -> good (ResolvesToNamespace (Set.findMin suffixNamespaceMatches))
(_, 0, 1) -> good (ResolvesToLocal (Set.findMin localMatches))
_ -> bad (Names.Ambiguous namespaceNames suffixNamespaceMatches localMatches)
where
bad = Left . Seq.singleton . Names.TypeResolutionFailure v a
good = Right . (v,)
Expand Down Expand Up @@ -96,12 +102,14 @@ bindNames unsafeVarToName nameToVar localVars namespaceNames ty =
localNames =
Set.map unsafeVarToName localVars

getNamespaceMatches :: Name -> Set TypeReference
getNamespaceMatches :: Name -> (Set TypeReference, Set TypeReference)
getNamespaceMatches name =
Names.lookupHQType
Names.IncludeSuffixes
(HQ.NameOnly name)
(over #types (Relation.subtractDom localNames) namespaceNames)
( Names.lookupHQType Names.ExactName (HQ.NameOnly name) namespaceNamesLessLocalNames,
Names.lookupHQType Names.IncludeSuffixes (HQ.NameOnly name) namespaceNamesLessLocalNames
)
where
namespaceNamesLessLocalNames =
over #types (Relation.subtractDom localNames) namespaceNames

getLocalMatches :: Name -> Set Name
getLocalMatches =
Expand Down
72 changes: 67 additions & 5 deletions unison-src/transcripts/name-resolution.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Example 1

We have a codebase type named `Codebase.Foo` and a file type named `File.Foo`. A reference to the type `Foo` is
ambiguous. A reference to `Codebase.Foo` or `File.Foo` work fine.
We have a namespace type named `Namespace.Foo` and a file type named `File.Foo`. A reference to the type `Foo` is
ambiguous. A reference to `Namespace.Foo` or `File.Foo` work fine.

```ucm
scratch/main> builtins.mergeio lib.builtins
```

```unison
type Codebase.Foo = Bar
type Namespace.Foo = Bar
```

```ucm
Expand All @@ -22,7 +22,7 @@ type UsesFoo = UsesFoo Foo

```unison
type File.Foo = Baz
type UsesFoo = UsesFoo Codebase.Foo File.Foo
type UsesFoo = UsesFoo Namespace.Foo File.Foo
```

```ucm
Expand All @@ -31,7 +31,69 @@ scratch/main> project.delete scratch

# Example 2

We have a codebase term `Woot.state : Nat` and a file term `Something.state : Text -> Something`. A reference to the
We have a namespace type named `Foo` and a file type named `File.Foo`. A reference to the type `Foo` is not ambiguous:
it refers to the namespace type (because it is an exact match).

```ucm
scratch/main> builtins.mergeio lib.builtins
```

```unison
type Foo = Bar
```

```ucm
scratch/main> add
```

```unison
type File.Foo = Baz
type UsesFoo = UsesFoo Foo
```

```ucm
scratch/main> add
scratch/main> view UsesFoo
```

```ucm
scratch/main> project.delete scratch
```

# Example 3

We have a namespace type named `Namespace.Foo` and a file type named `Foo`. A reference to the type `Foo` is not ambiguous:
it refers to the file type (because it is an exact match).

```ucm
scratch/main> builtins.mergeio lib.builtins
```

```unison
type Namespace.Foo = Bar
```

```ucm
scratch/main> add
```

```unison
type Foo = Baz
type UsesFoo = UsesFoo Foo
```

```ucm
scratch/main> add
scratch/main> view UsesFoo
```

```ucm
scratch/main> project.delete scratch
```

# Example 4

We have a namespace term `Woot.state : Nat` and a file term `Something.state : Text -> Something`. A reference to the
term `state : Text` resolves to `Something.state`, which shadows `Woot.state`. (This behavior will change).

```ucm
Expand Down
162 changes: 153 additions & 9 deletions unison-src/transcripts/name-resolution.output.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Example 1

We have a codebase type named `Codebase.Foo` and a file type named `File.Foo`. A reference to the type `Foo` is
ambiguous. A reference to `Codebase.Foo` or `File.Foo` work fine.
We have a namespace type named `Namespace.Foo` and a file type named `File.Foo`. A reference to the type `Foo` is
ambiguous. A reference to `Namespace.Foo` or `File.Foo` work fine.

``` ucm
scratch/main> builtins.mergeio lib.builtins
Expand All @@ -10,7 +10,7 @@ scratch/main> builtins.mergeio lib.builtins
```
``` unison
type Codebase.Foo = Bar
type Namespace.Foo = Bar
```

``` ucm
Expand All @@ -23,15 +23,15 @@ type Codebase.Foo = Bar
⍟ These new definitions are ok to `add`:
type Codebase.Foo
type Namespace.Foo
```
``` ucm
scratch/main> add
⍟ I've added these definitions:
type Codebase.Foo
type Namespace.Foo
```
``` unison
Expand All @@ -53,14 +53,14 @@ type UsesFoo = UsesFoo Foo
Symbol Suggestions
Foo Codebase.Foo
File.Foo
Foo File.Foo
Namespace.Foo
```
``` unison
type File.Foo = Baz
type UsesFoo = UsesFoo Codebase.Foo File.Foo
type UsesFoo = UsesFoo Namespace.Foo File.Foo
```

``` ucm
Expand All @@ -83,7 +83,151 @@ scratch/main> project.delete scratch
```
# Example 2

We have a codebase term `Woot.state : Nat` and a file term `Something.state : Text -> Something`. A reference to the
We have a namespace type named `Foo` and a file type named `File.Foo`. A reference to the type `Foo` is not ambiguous:
it refers to the namespace type (because it is an exact match).

``` ucm
scratch/main> builtins.mergeio lib.builtins
Done.
```
``` unison
type Foo = Bar
```

``` ucm
Loading changes detected in scratch.u.
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These new definitions are ok to `add`:
type Foo
```
``` ucm
scratch/main> add
⍟ I've added these definitions:
type Foo
```
``` unison
type File.Foo = Baz
type UsesFoo = UsesFoo Foo
```

``` ucm
Loading changes detected in scratch.u.
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These new definitions are ok to `add`:
type File.Foo
type UsesFoo
```
``` ucm
scratch/main> add
⍟ I've added these definitions:
type File.Foo
type UsesFoo
scratch/main> view UsesFoo
type UsesFoo = UsesFoo Foo
```
``` ucm
scratch/main> project.delete scratch
```
# Example 3

We have a namespace type named `Namespace.Foo` and a file type named `Foo`. A reference to the type `Foo` is not ambiguous:
it refers to the file type (because it is an exact match).

``` ucm
scratch/main> builtins.mergeio lib.builtins
Done.
```
``` unison
type Namespace.Foo = Bar
```

``` ucm
Loading changes detected in scratch.u.
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These new definitions are ok to `add`:
type Namespace.Foo
```
``` ucm
scratch/main> add
⍟ I've added these definitions:
type Namespace.Foo
```
``` unison
type Foo = Baz
type UsesFoo = UsesFoo Foo
```

``` ucm
Loading changes detected in scratch.u.
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These new definitions are ok to `add`:
type Foo
type UsesFoo
```
``` ucm
scratch/main> add
⍟ I've added these definitions:
type Foo
type UsesFoo
scratch/main> view UsesFoo
type UsesFoo = UsesFoo Foo
```
``` ucm
scratch/main> project.delete scratch
```
# Example 4

We have a namespace term `Woot.state : Nat` and a file term `Something.state : Text -> Something`. A reference to the
term `state : Text` resolves to `Something.state`, which shadows `Woot.state`. (This behavior will change).

``` ucm
Expand Down

0 comments on commit 25aeacd

Please sign in to comment.