snazzy-d/sdc

Cannot build simple program with empty `main`

WebDrake opened this issue · 7 comments

I recently built SDC from the current master (https://github.com/SDC-Developers/SDC/tree/95d690c349bbda539666c18db6aa59b42b91c3f7) using DMD 2.072.2 and LLVM 3.9.1. On trying to compile a simple no-op file:

void main ()
{
}

... I got a long stacktrace which suggests that something is failing during parsing:

$ sdc -c noop.d 
d.exception.CompileException@src/d/exception.d(15): expected 'Identifier', got 'Ulong'.
----------------
src/d/parser/base.d:21 void d.parser.base.match(ref d.lexer.TokenRange, d.lexer.TokenType) [0xacfaba]
src/d/parser/declaration.d:729 d.ast.declaration.Declaration d.parser.declaration.parseAlias(ref d.lexer.TokenRange, d.ast.declaration.StorageClass) [0xad765c]
src/d/parser/declaration.d:323 d.ast.declaration.Declaration d.parser.declaration.parseDeclaration(ref d.lexer.TokenRange) [0xadcc55]
src/d/parser/declaration.d:32 d.ast.declaration.Declaration[] d.parser.declaration.parseAggregate!(true).parseAggregate(ref d.lexer.TokenRange) [0xadde81]
src/d/parser/conditional.d:143 d.ast.declaration.Declaration[] d.parser.conditional.parseItems!(d.ast.declaration.Declaration).parseItems(ref d.lexer.TokenRange) [0xae0a36]
src/d/parser/conditional.d:68 d.ast.declaration.Declaration d.parser.conditional.parseconditionalBlock!(true, d.ast.declaration.Declaration).parseconditionalBlock(ref d.lexer.TokenRange) [0xae0cdc]
src/d/parser/conditional.d:16 d.ast.declaration.Declaration d.parser.conditional.parseVersion!(d.ast.declaration.Declaration).parseVersion(ref d.lexer.TokenRange) [0xae0bb4]
src/d/parser/declaration.d:71 d.ast.declaration.Declaration d.parser.declaration.parseDeclaration(ref d.lexer.TokenRange) [0xadc106]
src/d/parser/dmodule.d:40 d.ast.declaration.Module d.parser.dmodule.parseModule(ref d.lexer.TokenRange) [0xade650]
src/d/semantic/dmodule.d:97 d.ast.declaration.Module d.semantic.dmodule.ModuleVisitor.parse(immutable(char)[], immutable(char)[]) [0xb2797f]
src/d/semantic/dmodule.d:51 _D1d8semantic7dmodule13ModuleVisitor12importModuleMFAS1d7context4name4NameZ9__lambda3MFZC1d2ir6symbol6Module [0xb2747c]
src/d/semantic/dmodule.d:44 _D1d8semantic7dmodule13ModuleVisitor12importModuleMFAS1d7context4name4NameZ12__dgliteral4MFNaNiNfZC1d2ir6symbol6Module [0xb2735e]
/home/username/code/snap/sdc.snap/stage/bin/../import/object.d:2108 pure @safe inout(d.ir.symbol.Module) object.get!(immutable(char)[], d.ir.symbol.Module).get(inout(d.ir.symbol.Module[immutable(char)[]]), immutable(char)[], lazy inout(d.ir.symbol.Module)) [0xa5e568]
src/d/semantic/dmodule.d:58 d.ir.symbol.Module d.semantic.dmodule.ModuleVisitor.importModule(d.context.name.Name[]) [0xb2733b]
src/d/semantic/semantic.d:109 d.ir.symbol.Module d.semantic.semantic.SemanticPass.importModule(d.context.name.Name[]) [0xb35051]
src/d/semantic/semantic.d:75 d.semantic.semantic.SemanticPass d.semantic.semantic.SemanticPass.__ctor(d.context.context.Context, d.semantic.evaluator.Evaluator delegate(d.semantic.scheduler.Scheduler, d.object.ObjectReference), d.semantic.datalayout.DataLayout delegate(d.object.ObjectReference)) [0xb34cf5]
src/sdc/sdc.d:62 sdc.sdc.SDC sdc.sdc.SDC.__ctor(immutable(char)[], sdc.util.json.JSON, d.context.config.Config) [0x9df606]
src/driver/sdc.d:79 _Dmain [0x9c72b8]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0xb719e6]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0xb71930]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0xb719a2]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0xb71930]
??:? _d_run_main [0xb718a1]
??:? main [0x9dcea1]
??:? __libc_start_main [0xcaf7e82f]

Note, I built SDC using a snap package definition, where DMD 2.072.2 and LLVM 3.9.1 are built first and then used to build SDC itself, but I doubt that will have had an influence given the nature of the error message. I can share that package definition if you think it would be relevant/useful.

I had posted a reply that — based on a coincidence found when skimming your error in a cramped mobile Gmail client — decided it could be fruitful to willfully ignore the expected form of a D stack trace and instead hope that a particular line in your stacktrace was instead actually debug information injected by the SDC compiler. Looking at your post in a full browser, and not just as an email, it's clear that that's not what that line was, so you can safely ignore my previously posted tip.

Unfortunately, it seems that CompileException is not made to actually output any of the info it has on the location of the error by default, but looking through the code, it looks like SDC tries to catch the CompileException at all the points where such an exception might escape to the user, and then manually extracts and prints that most-useful bit of diagnostic information (which should make that point moot):

	} catch(CompileException e) {
		import util.terminal;
		outputCaretDiagnostics(e.getFullLocation(c.context), e.msg);
		
		// Rethrow in debug, so we have the stack trace.
		debug {
			throw e;
		} else {
			return 1;
		}
	}

Are you sure there is no other output describing where SDC was expecting an identifier but got a ulong instead? And if not, what the does the lack of that information imply? Apparently the try block that prints that info isn't expansive enough to be helpful in your case... It doesn't include the compiler's constructor, and apparently (from your stack trace) much of the parsing actually happens right inside the compiler's constructor o_O. Something about that design should be changed for SDC, but for your purposes, it seems that altering the try block within your local copy of the src/driver/sdc.d file to include the SDC constructor a few lines above should allow you get some more useful info on what's actually happening.

Make sure your sdc.conf file does looks right. Worst case scenario delete it and let it regenerate. It looks like it isn't looking for the right object.d .

Make sure your sdc.conf file does looks right. Worst case scenario delete it and let it regenerate. It looks like it isn't looking for the right object.d .

I presume you mean this line?

/home/username/code/snap/sdc.snap/stage/bin/../import/object.d:2108 pure @safe inout(d.ir.symbol.Module) object.get!(immutable(char)[], d.ir.symbol.Module).get(inout(d.ir.symbol.Module[immutable(char)[]]), immutable(char)[], lazy inout(d.ir.symbol.Module)) [0xa5e568]

I think this is simply an artefact of how the compiler was built: that was the location of the Phobos object.d of the DMD used to build SDC.

I'll look into the other points raised further in the coming week.

I presume that you are using DMD's object.d instead of SDC's.

I presume that you are using DMD's object.d instead of SDC's.

Ah, I see what you mean. So the *.d files from the sdlib directory are expected to be included in the install? Any particular constraints on their location?

Just to confirm, it was the choice of object.d: a mistake in how I was setting up the snap package definition. All working now; thanks for the assistance!

I'll share the package definition later in the week if you're interested: it might be useful for some forms of CI (or just for a simple way for people to build and install something working from master).