#path: a.b

TODO: some alternative behaviors to consider here:
- inline small values, even in expressions.
- fail if hoisting results in an impossible expression,
  such as: `foo[string]` or `{}.foo`.
- evaluate expressions to completion, if possible.

-- in.cue --
x: map: {foo: int}
y: z: map: {bar: int}

incomplete1: string
incomplete2: string
completeExist: "foo"
completeNotExist: "bar"

a: b: {
	ref1: x.map
	ref2: x.map.foo
	ref3: x.map[incomplete1]      // always an error
	ref4: x.map[completeExist]    // can be simplified
	ref5: x.map[completeNotExist] // always an error

	ref6: y.z.map[incomplete2] // inline the single-use map.
}
-- out/self/default --
ref1: MAP
ref2: MAP.foo
ref3: MAP[INCOMPLETE1]
ref4: MAP.foo
ref5: MAP["bar"]
ref6: MAP_1[INCOMPLETE2]

//cue:path: x.map
let MAP = {
	foo: int
}

//cue:path: incomplete1
let INCOMPLETE1 = string

//cue:path: y.z.map
let MAP_1 = {
	bar: int
}

//cue:path: incomplete2
let INCOMPLETE2 = string
