diff --git a/changelog/multi_module_selective_imports.dd b/changelog/multi_module_selective_imports.dd new file mode 100644 index 000000000000..80e691f32ab4 --- /dev/null +++ b/changelog/multi_module_selective_imports.dd @@ -0,0 +1,19 @@ +Allow multiple selective imports from different modules in a single import statement + +It is now possible to add imports from a different module after a selective +import list, when those import are also selective or when the imported module +has a qualified name. + +------- +import pkg.mod1 : sym1, mod2 : sym2; +import pkg.mod1 : sym1, sym2, pkg.mod2; +------- + +Unqualified modules or renamed imports following a selective import will be +parsed as part of the selective import list, not as separate modules. + +------- +import pkg.mod1 : sym1, mod2; // selectively imports mod2 from pkg.mod1 +import pkg.mod1 : sym1, name=mod2; // selectively imports mod2 as name from pkg.mod1 +import pkg.mod1 : sym1, name=pkg1.mod1; // parsing renamed selective imports fails due to qualfier +------- diff --git a/src/dmd/parse.d b/src/dmd/parse.d index 480444b63a52..68a3d43a9954 100644 --- a/src/dmd/parse.d +++ b/src/dmd/parse.d @@ -3282,9 +3282,15 @@ final class Parser(AST) : Lexer _alias = null; } s.addAlias(name, _alias); + if (token.value != TOKcomma) + break; + // recognize import pkg.mod1 : a, b, pkg.mod2; + immutable afterIdent = peekNext2; + if (peekNext2 == TOKdot || // pkg . mod2 + peekNext2 == TOKcolon) // mod2 : c + break; // parse another import } while (token.value == TOKcomma); - break; // no comma-separated imports of this form } aliasid = null; } diff --git a/test/compilable/enh13855.d b/test/compilable/enh13855.d new file mode 100644 index 000000000000..2702268b0901 --- /dev/null +++ b/test/compilable/enh13855.d @@ -0,0 +1,3 @@ +import imports.pkg313.c313 : bug, imports.c314 : bug; // previously 2 import statements +import imports.pkg313.c313 : bug, imports.c314; // also allows qualified module w/o selective import +import imports.c314, imports.pkg313.c313 : bug; // unchanged diff --git a/test/fail_compilation/enh13855a.d b/test/fail_compilation/enh13855a.d new file mode 100644 index 000000000000..e523532b2a08 --- /dev/null +++ b/test/fail_compilation/enh13855a.d @@ -0,0 +1,8 @@ +/* +TEST_OUTPUT: +---- +fail_compilation/enh13855a.d(7): Error: module imports.c314 import 'enh13855a' not found +---- +*/ +import imports.c314 : bug, enh13855a; // unqualified module would be ambiguous, parsed as symbol +import enh13855a, imports.c314 : bug; // works unchanged diff --git a/test/fail_compilation/enh13855b.d b/test/fail_compilation/enh13855b.d new file mode 100644 index 000000000000..91422d6a4b45 --- /dev/null +++ b/test/fail_compilation/enh13855b.d @@ -0,0 +1,10 @@ +/* +REQUIRED_ARGS: -vcolumns +TEST_OUTPUT: +---- +fail_compilation/enh13855b.d(9,47): Error: `;` expected +fail_compilation/enh13855b.d(9,52): Error: no identifier for declarator `c314` +---- +*/ +import imports.pkg313.c313 : bug, name=imports.c314; // aliased module would require arbitrary lookahead +import name=imports.c314, imports.pkg313.c313 : bug; // works, unchanged