Ticket Created
over 3 years ago

CIQQA-1388

import/using are not scoped correctly by the new compiler

Demo code:

import Toybox.Test;
import Toybox.Lang;

module ImportWeirdness {
    module Strange {
        import ImportWeirdness.ImportedOutOfScope;
    }
    module NotImported {
        const K = 0;
    }
    module ImportedInScope {
        const K = 1;
    }
    module ImportedOutOfScope {
        const K = 2;
    }
    module Nest {
        import ImportWeirdness.ImportedInScope;
        module NotImported {
            const K = 3;
        }
        module ImportedInScope {
            const K = 4;
        }
        module ImportedOutOfScope {
            const K = 5;
        }
        (:test)
        function test(logger as Logger) as Boolean {
            var ok = true;
            if (NotImported.K != 3) {
                logger.debug(
                    "NotImported.K was " + NotImported.K.toString() + " not 3"
                );
                ok = false;
            }
            if (ImportedInScope.K != 1) {
                logger.debug(
                    "ImportedInScope.K was " +
                        ImportedInScope.K.toString() +
                        " not 1"
                );
                ok = false;
            }
            if (ImportedOutOfScope.K != 5) {
                logger.debug(
                    "ImportedOutOfScope.K was " +
                        ImportedOutOfScope.K.toString() +
                        " not 5"
                );
                ok = false;
            }
            return ok;
        }
    }
}

The issue here relates to how import/using prioritizes the imported module.

  • When there are no imports, the search for a name goes strictly from inner scopes to outer scopes, so when looking up NotImported.K it finds the nearest one, namely $.ImportWeirdness.Nest.NotImported.K. This works with the old and new compilers.
  • When a module is imported, and the import is in scope, the import takes priority, so ImportedInScope.K resolves to $.ImportWeirdness.ImportedInScope.K, rather than $.ImportWeirdness.Nest.ImportedInScope.K. Again, this works with both the old and new compilers.
  • When a module is imported, but the import is *not* in scope, the import should have no effect. So ImportedOutOfScope.K should resolve to $.ImportWeirdness.Nest.ImportedOutOfScope.K, and it does in the old compiler, but in the new compiler it behaves as if the import was in scope, and resolves to $.ImportWeirdness.ImportedOutOfScope.K

The result is that the test passes on the old compiler, and fails on the new.