diff --git a/parser-typechecker/src/Unison/Syntax/DeclParser.hs b/parser-typechecker/src/Unison/Syntax/DeclParser.hs index 1f2e4f564e..a2bedcc4bc 100644 --- a/parser-typechecker/src/Unison/Syntax/DeclParser.hs +++ b/parser-typechecker/src/Unison/Syntax/DeclParser.hs @@ -87,7 +87,7 @@ modifierP = do where unique = do tok <- openBlockWith "unique" - optional (openBlockWith "[" *> importWordyId <* closeBlock) >>= \case + optional (openBlockWith "[" *> importRelativeWordyId <* closeBlock) >>= \case Nothing -> pure (UnresolvedModifier'UniqueWithoutGuid <$ tok) Just guid -> pure (UnresolvedModifier'UniqueWithGuid (Name.toText (L.payload guid)) <$ tok) structural = do diff --git a/parser-typechecker/src/Unison/Syntax/FileParser.hs b/parser-typechecker/src/Unison/Syntax/FileParser.hs index 65c217a2cb..08091cf489 100644 --- a/parser-typechecker/src/Unison/Syntax/FileParser.hs +++ b/parser-typechecker/src/Unison/Syntax/FileParser.hs @@ -55,7 +55,7 @@ file = do optional (reserved "namespace") >>= \case Nothing -> pure Nothing Just _ -> do - namespace <- importWordyId <|> importSymbolyId + namespace <- importRelativeWordyId <|> importRelativeSymbolyId void (optional semi) pure (Just namespace.payload) let maybeNamespaceVar = Name.toVar <$> maybeNamespace @@ -401,9 +401,9 @@ stanza = watchExpression <|> unexpectedAction <|> binding watched :: (Monad m, Var v) => P v m (UF.WatchKind, Text, Ann) watched = P.try do - kind <- (fmap . fmap . fmap) (Text.unpack . Name.toText) (optional importWordyId) + kind <- (fmap . fmap . fmap) (Text.unpack . Name.toText) (optional importRelativeWordyId) guid <- uniqueName 10 - op <- optional (L.payload <$> P.lookAhead importSymbolyId) + op <- optional (L.payload <$> P.lookAhead importRelativeSymbolyId) guard (op == Just (Name.fromSegment NameSegment.watchSegment)) tok <- anyToken guard $ maybe True (`L.touches` tok) kind diff --git a/parser-typechecker/src/Unison/Syntax/TermParser.hs b/parser-typechecker/src/Unison/Syntax/TermParser.hs index 97914aabfa..7e35241593 100644 --- a/parser-typechecker/src/Unison/Syntax/TermParser.hs +++ b/parser-typechecker/src/Unison/Syntax/TermParser.hs @@ -1355,7 +1355,7 @@ importp = do optional $ fmap Right importWordyId <|> fmap Left importSymbolyId - suffixes <- optional (some (importWordyId <|> importSymbolyId)) + suffixes <- optional (some (importRelativeWordyId <|> importRelativeSymbolyId)) case (prefix, suffixes) of (Nothing, _) -> P.customFailure $ UseEmpty kw (Just prefix@(Left _), _) -> P.customFailure $ UseInvalidPrefixSuffix prefix suffixes diff --git a/unison-src/transcripts/idempotent/fix-4536.md b/unison-src/transcripts/idempotent/fix-4536.md index a17052e8f6..c23fdee84a 100644 --- a/unison-src/transcripts/idempotent/fix-4536.md +++ b/unison-src/transcripts/idempotent/fix-4536.md @@ -40,32 +40,6 @@ foo = * typeLink ``` -``` unison :error -foo : Nat -foo = - use .lib.builtin.Nat + - 1 + 2 -``` - -``` ucm :added-by-ucm - Loading changes detected in scratch.u. - - 😶 - - I was expecting something after the use keyword - - 3 | use .lib.builtin.Nat + - - Here's a few examples of valid `use` statements: - - use math sqrt Introduces `sqrt` as a local alias for - `math.sqrt` - use List :+ Introduces `:+` as a local alias for - `List.:+`. - use .foo bar.baz Introduces `bar.baz` as a local alias for - the absolute name `.foo.bar.baz` -``` - ``` unison :error namespace .foo ``` diff --git a/unison-syntax/src/Unison/Syntax/Parser.hs b/unison-syntax/src/Unison/Syntax/Parser.hs index e6afe27a06..e109874674 100644 --- a/unison-syntax/src/Unison/Syntax/Parser.hs +++ b/unison-syntax/src/Unison/Syntax/Parser.hs @@ -24,6 +24,8 @@ module Unison.Syntax.Parser failureIf, hqInfixId, hqPrefixId, + importRelativeSymbolyId, + importRelativeWordyId, importSymbolyId, importWordyId, label, @@ -357,15 +359,27 @@ wordyDefinitionName = queryToken \case L.WordyId n -> Just $ Name.toVar (HQ'.toName n) _ -> Nothing --- | Parse a wordyId as a relative Name, rejecting any hash +-- | Parse a wordyId as a Name, rejecting any hash importWordyId :: (Ord v) => P v m (L.Token Name) importWordyId = queryToken \case + L.WordyId (HQ'.NameOnly n) -> Just n + _ -> Nothing + +-- | Parse a wordyId as a relative Name, rejecting any hash +importRelativeWordyId :: (Ord v) => P v m (L.Token Name) +importRelativeWordyId = queryToken \case L.WordyId (HQ'.NameOnly n) | Name.isRelative n -> Just n _ -> Nothing --- | The `+` in: use Foo.bar + as a relative Name +-- | The `+` in: use Foo.bar + as a Name importSymbolyId :: (Ord v) => P v m (L.Token Name) importSymbolyId = queryToken \case + L.SymbolyId (HQ'.NameOnly n) -> Just n + _ -> Nothing + +-- | The `+` in: use Foo.bar + as a relative Name +importRelativeSymbolyId :: (Ord v) => P v m (L.Token Name) +importRelativeSymbolyId = queryToken \case L.SymbolyId (HQ'.NameOnly n) | Name.isRelative n -> Just n _ -> Nothing