Skip to content

Introduce Import Resolution as a Frontend Action #17645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 13, 2018

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Jun 29, 2018

Add Name Binding Import Resolution as a frontend action to make computing dependencies cheaper by no longer going through the type checker. Also includes corrections and additions to the diagnostics for misuse of -emit-reference-dependencies and -emit-dependencies when in parse-only contexts.

@@ -884,6 +884,79 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals) {
"Loaded a module during parse-only");
}

void CompilerInstance::performParseAndNameBindingOnly() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this share code with any of the other actions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can probably fold it into performSema now, but we may not necessarily be calling performNameBinding in the future for this path.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, something about this feels a bit wrong to me too: the extent to which performParseOnly and the parsing-part of parseAndCheckTypes have already diverged seems regrettable, and this is just going to keep digging that hole by further duplicating and diverging. Can we refactor these paths without making them awful?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm emphatically with Graydon and Slava here. It already really bothers me that there were two main routines, performParseOnly and performSema. You would be doing the code base a great service if you could figure out how to factor these together so it were crystal clear which operations went with which alternative and which ones were common.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think performParseOnly and performSema actually are significantly different, but performSema and this new operation are not. Please do make this a mode for performSema instead.

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My primary comment is that if you're going to do this, that means it's time to fix the name of the pass. :-) It should be "perform import resolution" or even just "resolve imports". Arguably the parts that handle operators don't even belong here; they just save a top-level AST walk. We could just as easily move that into early type checking, like we do with extension binding.

@@ -884,6 +884,79 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals) {
"Loaded a module during parse-only");
}

void CompilerInstance::performParseAndNameBindingOnly() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think performParseOnly and performSema actually are significantly different, but performSema and this new operation are not. Please do make this a mode for performSema instead.

CodaFi added 2 commits July 13, 2018 10:56
Parse-only invocations do not support the proper creation of dependency files or reference dependency files because they have not yet run name binding.  Ban these invocations by diagnostic and add a new diagnostic specifically for reference dependencies.
Introduces the -name-bind frontend action that is intended as an intermediary between the parse-only actions and a full typechecking pass.  In this phase, module imports will be validated and resolved, making it possible to emit full make-style dependencies files among other things.

Note that all information available to a parse-only pass is available to name binding, but because it does not continue-on to typecheck input files, full semantic information is not.
@CodaFi CodaFi force-pushed the name-binding-arbitration branch from 032b053 to 575d6eb Compare July 13, 2018 17:56
@CodaFi CodaFi changed the title Introduce Name Binding as a Frontend Action Introduce Import Resolution as a Frontend Action Jul 13, 2018
@CodaFi CodaFi force-pushed the name-binding-arbitration branch from 575d6eb to 2282065 Compare July 13, 2018 18:01
Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good to me, only minor comments.

@@ -425,7 +425,21 @@ shouldImplicityImportSwiftOnoneSupportModule(CompilerInvocation &Invocation) {
return Invocation.getFrontendOptions().isCreatingSIL();
}

void CompilerInstance::performParseAndResolveImportsOnly() {
performSemaUpTo(SourceFile::NameBound);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm personally not sure we need these helper functions, and think we could just add an argument to performSema (and deprecate performParseOnly later). But either way is okay with me.

case ActionType::EmitBC:
case ActionType::EmitAssembly:
case ActionType::EmitObject:
case ActionType::EmitImportedModules:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if -emit-imported-modules should be demoted from an action later…

@@ -227,6 +263,7 @@ bool FrontendOptions::canActionEmitObjCHeader(ActionType action) {
case ActionType::REPL:
return false;
case ActionType::Parse:
case ActionType::ResolveImports:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think Parse and ResolveImports belong in the "false" section for this one. It definitely needs a type-checked AST.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll submit another patch for that one.

@@ -929,8 +939,6 @@ static bool performCompile(CompilerInstance &Instance,
debugFailWithCrash();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arguably these crashes should happen even in -parse or -resolve-imports.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future reference: Had an offline chat about this. Filed SR-8252 about it.

ERROR(error_mode_cannot_emit_module_doc,none,
"this mode does not support emitting module documentation files", ())
"this mode does not support emitting module documentation files", ())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you feel like it, it would be nice to actually include the referred-to mode in the error message. I understand if it's outside the scope of this change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these errors are already caught at the driver level, so checking for them in the frontend just helps test authors. That means there's not really a problem with talking about specific frontend arguments, which I'd normally be worried about.

@davidungar
Copy link
Contributor

Someday, when I'm back into this code, I'll be wondering what is this new mode (up to name-binding) for? Is there a comment somewhere that explains? Could there be?

Copy link
Contributor

@davidungar davidungar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only significant thought I have is the comment about what the purpose of the new functionality is for. In other words, what would I be breaking if I messed this up in the future? When is the compiler invoked in this mode?? Otherwise, LGTM.

@CodaFi
Copy link
Contributor Author

CodaFi commented Jul 13, 2018

Is there a comment somewhere that explains?

There is not currently an up-to-date definition of what name binding is actually supposed to be doing (that is, you can find resources like the old and new LangRefs in the docs folder that describe what it certainly used to do).

Could there be?

Certainly. All these actions should be documented as much. Which interface would you like me to attach these comments to?

@jrose-apple
Copy link
Contributor

jrose-apple commented Jul 13, 2018

Either @CodaFi or I will probably go back afterwards and replace the other instances of "NameBinding" with "ImportResolution" elsewhere in the compiler. That'd be a reasonable time to pump up documentation, say in SourceFile::ASTStage_t.

@CodaFi
Copy link
Contributor Author

CodaFi commented Jul 13, 2018

Alright, thanks for the feedback.

⛵️

@swift-ci please smoke test and merge

@swift-ci swift-ci merged commit 751ffa4 into swiftlang:master Jul 13, 2018
@CodaFi CodaFi deleted the name-binding-arbitration branch July 13, 2018 21:56
@davidungar
Copy link
Contributor

davidungar commented Jul 13, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants