on master help sign in
When canonicalizing, prefer local definitions
commit440c18286c5ad358985a817bf086dabedb8fd37e authorEvan Czaplicki <info@elm-lang.org> dateWed 28 May 2014, 19:13 (12 years ago) parentdfdf96d
1 file changed+36−19
compiler/Transform/Canonicalize/Variable.hs+36−19
compiler/Transform/Canonicalize/Variable.hs+36−19
@@ -1,4 +1,4 @@
1−{-# OPTIONS_GHC -W #-}
1+{-# OPTIONS_GHC -Wall #-}
22module Transform.Canonicalize.Variable where
33
44import qualified Data.List as List
@@ -20,45 +20,62 @@ variable env var =
2020
2121 _ -> case Map.lookup var (_values env) of
2222 Just [v] -> return v
23− Just vs -> Left (ambiguous "variable" (map Var.toString vs) var)
24− Nothing -> Left (notFound "variable" (Map.keys (_values env)) var)
23+ Just vs -> preferLocals "variable" vs var
24+ Nothing -> notFound "variable" (Map.keys (_values env)) var
2525 where
2626 (modul, name) = case Help.splitDots var of
2727 [x] -> (Nothing, x)
2828 xs -> (Just (init xs), last xs)
2929
3030tvar :: Environment -> String
31− -> Either String (Either Var.Canonical (Var.Canonical, [String], Type.Type Var.Canonical))
31+ -> Either String (Either Var.Canonical (Var.Canonical, [String], Type.CanonicalType))
3232tvar env var =
3333 case adts ++ aliases of
34− [] -> Left $ notFound "type" (Map.keys (_adts env) ++ Map.keys (_aliases env)) var
34+ [] -> notFound "type" (Map.keys (_adts env) ++ Map.keys (_aliases env)) var
3535 [v] -> return v
36− vs -> Left $ ambiguous "type" (map toString vs) var
36+ vs -> preferLocals' extract "type" vs var
3737 where
38− adts = map Left . fromMaybe [] $ Map.lookup var (_adts env)
38+ adts = map Left . fromMaybe [] $ Map.lookup var (_adts env)
3939 aliases = map Right . fromMaybe [] $ Map.lookup var (_aliases env)
40− toString v =
41− Var.toString $ case v of
42− Left x -> x
43− Right (x,_,_) -> x
40+
41+ extract value =
42+ case value of
43+ Left v -> v
44+ Right (v,_,_) -> v
4445
4546pvar :: Environment -> String -> Either String Var.Canonical
4647pvar env var =
4748 case Map.lookup var (_patterns env) of
4849 Just [v] -> return v
49− Just vs -> Left (ambiguous "pattern" (map Var.toString vs) var)
50− Nothing -> Left (notFound "pattern" (Map.keys (_patterns env)) var)
50+ Just vs -> preferLocals "pattern" vs var
51+ Nothing -> notFound "pattern" (Map.keys (_patterns env)) var
5152
52−notFound :: String -> [String] -> String -> String
53+notFound :: String -> [String] -> String -> Either String a
5354notFound kind possibilities var =
54− "Could not find " ++ kind ++ " '" ++ var ++ "'." ++ msg
55+ Left $ "Could not find " ++ kind ++ " '" ++ var ++ "'." ++ msg
5556 where
5657 matches = filter (List.isInfixOf var) possibilities
5758 msg = if null matches then "" else
5859 "\nClose matches include: " ++ List.intercalate ", " matches
5960
60−ambiguous :: String -> [String] -> String -> String
61−ambiguous kind possibilities var =
62− "Ambiguous usage of " ++ kind ++ " '" ++ var ++ "'.\n" ++
63− " Disambiguate between: " ++ List.intercalate ", " possibilities
61+preferLocals :: String -> [Var.Canonical] -> String -> Either String Var.Canonical
62+preferLocals = preferLocals' id
63+
64+preferLocals' :: (a -> Var.Canonical) -> String -> [a] -> String -> Either String a
65+preferLocals' extract kind possibilities var =
66+ case filter (isLocal . extract) possibilities of
67+ [] -> ambiguous possibilities
68+ [v] -> return v
69+ locals -> ambiguous locals
70+ where
71+ isLocal :: Var.Canonical -> Bool
72+ isLocal (Var.Canonical Var.Local _) = True
73+ isLocal (Var.Canonical _ _) = False
74+
75+ ambiguous possibleVars =
76+ Left msg
77+ where
78+ vars = map (Var.toString . extract) possibleVars
79+ msg = "Ambiguous usage of " ++ kind ++ " '" ++ var ++ "'.\n" ++
80+ " Disambiguate between: " ++ List.intercalate ", " vars
6481