From 061acd3ce9e1af12695b7387b42218fc99a8d91b Mon Sep 17 00:00:00 2001 From: som-snytt Date: Tue, 17 May 2016 02:58:17 -0700 Subject: SI-2458 Clarify spec for package syms (#5151) Package definitions are priority 4. Update the big example to be cut/pastable. --- spec/02-identifiers-names-and-scopes.md | 91 +++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/spec/02-identifiers-names-and-scopes.md b/spec/02-identifiers-names-and-scopes.md index 0a9c5dfe77..6653be2ce5 100644 --- a/spec/02-identifiers-names-and-scopes.md +++ b/spec/02-identifiers-names-and-scopes.md @@ -17,12 +17,12 @@ which are collectively called _bindings_. Bindings of different kinds have a precedence defined on them: 1. Definitions and declarations that are local, inherited, or made - available by a package clause in the same compilation unit where the - definition occurs have highest precedence. + available by a package clause and also defined in the same compilation unit + as the reference, have highest precedence. 1. Explicit imports have next highest precedence. 1. Wildcard imports have next highest precedence. -1. Definitions made available by a package clause not in the - compilation unit where the definition occurs have lowest precedence. +1. Definitions made available by a package clause, but not also defined in the + same compilation unit as the reference, have lowest precedence. There are two different name spaces, one for [types](03-types.html#types) and one for [terms](06-expressions.html#expressions). The same name may designate a @@ -34,22 +34,18 @@ in some inner scope _shadows_ bindings of lower precedence in the same scope as well as bindings of the same or lower precedence in outer scopes. - - A reference to an unqualified (type- or term-) identifier $x$ is bound by the unique binding, which @@ -69,17 +65,36 @@ the member of the type $T$ of $e$ which has the name $x$ in the same namespace as the identifier. It is an error if $T$ is not a [value type](03-types.html#value-types). The type of $e.x$ is the member type of the referenced entity in $T$. +Binding precedence implies that the way source is bundled in files affects name resolution. +In particular, imported names have higher precedence than names, defined in other files, +that might otherwise be visible because they are defined in +either the current package or an enclosing package. + +Note that a package definition is taken as lowest precedence, since packages +are open and can be defined across arbitrary compilation units. + +```scala +package util { + import scala.util + class Random + object Test extends App { + println(new util.Random) // scala.util.Random + } +} +``` + ###### Example -Assume the following two definitions of objects named `X` in packages `P` and `Q`. +Assume the following two definitions of objects named `X` in packages `p` and `q` +in separate compilation units. ```scala -package P { +package p { object X { val x = 1; val y = 2 } } -package Q { - object X { val x = true; val y = "" } +package q { + object X { val x = true; val y = false } } ``` @@ -87,25 +102,27 @@ The following program illustrates different kinds of bindings and precedences between them. ```scala -package P { // `X' bound by package clause -import Console._ // `println' bound by wildcard import -object A { - println("L4: "+X) // `X' refers to `P.X' here - object B { - import Q._ // `X' bound by wildcard import - println("L7: "+X) // `X' refers to `Q.X' here - import X._ // `x' and `y' bound by wildcard import - println("L8: "+x) // `x' refers to `Q.X.x' here - object C { - val x = 3 // `x' bound by local definition - println("L12: "+x) // `x' refers to constant `3' here - { import Q.X._ // `x' and `y' bound by wildcard import -// println("L14: "+x) // reference to `x' is ambiguous here - import X.y // `y' bound by explicit import - println("L16: "+y) // `y' refers to `Q.X.y' here - { val x = "abc" // `x' bound by local definition - import P.X._ // `x' and `y' bound by wildcard import -// println("L19: "+y) // reference to `y' is ambiguous here - println("L20: "+x) // `x' refers to string "abc" here +package p { // `X' bound by package clause +import Console._ // `println' bound by wildcard import +object Y { + println(s"L4: $X") // `X' refers to `p.X' here + locally { + import q._ // `X' bound by wildcard import + println(s"L7: $X") // `X' refers to `q.X' here + import X._ // `x' and `y' bound by wildcard import + println(s"L9: $x") // `x' refers to `q.X.x' here + locally { + val x = 3 // `x' bound by local definition + println(s"L12: $x") // `x' refers to constant `3' here + locally { + import q.X._ // `x' and `y' bound by wildcard import +// println(s"L15: $x") // reference to `x' is ambiguous here + import X.y // `y' bound by explicit import + println(s"L17: $y") // `y' refers to `q.X.y' here + locally { + val x = "abc" // `x' bound by local definition + import p.X._ // `x' and `y' bound by wildcard import +// println(s"L21: $y") // reference to `y' is ambiguous here + println(s"L22: $x") // `x' refers to string "abc" here }}}}}} ``` -- cgit v1.2.3