Skip to content

Basic: out-of-line equality operator (NFCI) #29032

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 1 commit into from
Jan 7, 2020

Conversation

compnerd
Copy link
Member

@compnerd compnerd commented Jan 6, 2020

MSVC did not like the original code and would fail to build as:

swift\include\swift/Basic/Located.h(50): error C2995: 'bool swift::operator ==(const swift::Located<T> &,const swift::Located<T> &)': function template has already been defined
swift\include\swift/Basic/Located.h(50): note: see declaration of 'swift::operator =='
llvm\include\llvm/Support/TrailingObjects.h(76): note: see reference to class template instantiation 'swift::Located<swift::Identifier>' being compiled
llvm\include\llvm/Support/TrailingObjects.h(233): note: see reference to class template instantiation 'llvm::trailing_objects_internal::AlignmentCalcHelper<swift::Located<swift::Identifier>>' being compiled
swift\include\swift/AST/Decl.h(1512): note: see reference to class template instantiation 'llvm::TrailingObjects<swift::ImportDecl,swift::Located<swift::Identifier>>' being compiled

The original code is odd. There appears to be some unnecessary
complexity.

First, the member function is marked as a friend of a
struct type which does not change the member's visibility, thus all
the members are public, and the function need not be friended.

Second, the function is templated over the same parameter type, which
means that the original template parameter could be used and the
standard member equality operator could be used rather than the
free-standing form.

It is unclear why the member equality operator is insufficient, and the
extraneous template instatiations here seem wasteful. Out-of-line the
free-standing form and not mark it as a friend to restore the build.
Switching to a member form can be a follow up change.

Replace this paragraph with a description of your changes and rationale. Provide links to external references/discussions if appropriate.

Resolves SR-NNNN.

MSVC did not like the original code and would fail to build as:

  ```
  swift\include\swift/Basic/Located.h(50): error C2995: 'bool swift::operator ==(const swift::Located<T> &,const swift::Located<T> &)': function template has already been defined
  swift\include\swift/Basic/Located.h(50): note: see declaration of 'swift::operator =='
  llvm\include\llvm/Support/TrailingObjects.h(76): note: see reference to class template instantiation 'swift::Located<swift::Identifier>' being compiled
  llvm\include\llvm/Support/TrailingObjects.h(233): note: see reference to class template instantiation 'llvm::trailing_objects_internal::AlignmentCalcHelper<swift::Located<swift::Identifier>>' being compiled
  swift\include\swift/AST/Decl.h(1512): note: see reference to class template instantiation 'llvm::TrailingObjects<swift::ImportDecl,swift::Located<swift::Identifier>>' being compiled
  ```

The original code is odd.  There appears to be some unnecessary
complexity.

First, the member function is marked as a friend of a
`struct` type which does not change the member's visibility, thus all
the members are `public`, and the function need not be friended.

Second, the function is templated over the same parameter type, which
means that the original template parameter could be used and the
standard member equality operator could be used rather than the
free-standing form.

It is unclear why the member equality operator is insufficient, and the
extraneous template instatiations here seem wasteful.  Out-of-line the
free-standing form and not mark it as a friend to restore the build.
Switching to a member form can be a follow up change.
@compnerd
Copy link
Member Author

compnerd commented Jan 6, 2020

CC: @varungandhi-apple

@compnerd
Copy link
Member Author

compnerd commented Jan 6, 2020

@swift-ci please smoke test

@compnerd
Copy link
Member Author

compnerd commented Jan 6, 2020

CC: @CodaFi

@compnerd
Copy link
Member Author

compnerd commented Jan 7, 2020

@swift-ci please test macOS platform

@compnerd
Copy link
Member Author

compnerd commented Jan 7, 2020

@swift-ci please smoke test macOS platform

@varungandhi-apple
Copy link
Contributor

Now I'm wondering why it didn't fail with clang. Does this lead to an ODR violation? It seems a bit odd that one compiler errors for it and another one lets it through. Maybe it is a clang bug?

@compnerd
Copy link
Member Author

compnerd commented Jan 7, 2020

It shouldn't really result in an ODR violation, the template types should get coalesced by the linker and you should end up with a single instance of it. I would agree that clang could detect this and warn on it.

@compnerd
Copy link
Member Author

compnerd commented Jan 7, 2020

@varungandhi-apple, seems related to your subsequent change:

/Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2174:24: error: no member named 'empty' in 'swift::Located<llvm::StringRef>'
16:17:48     if (conv.ClangType.empty())
16:17:48         ~~~~~~~~~~~~~~ ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2177:21: error: no member named 'ClangTypeLoc' in 'swift::TypeAttributes::Convention'; did you mean 'ClangType'?
16:17:48       diagnose(conv.ClangTypeLoc,
16:17:48                     ^~~~~~~~~~~~
16:17:48                     ClangType
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/Attr.h:73:24: note: 'ClangType' declared here
16:17:48     Located<StringRef> ClangType = Located<StringRef>(StringRef(), {});
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2184:51: error: no member named 'ClangTypeLoc' in 'swift::TypeAttributes::Convention'
16:17:48       Context.SourceMgr.getDisplayNameForLoc(conv.ClangTypeLoc);
16:17:48                                              ~~~~ ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2187:61: error: no member named 'ClangTypeLoc' in 'swift::TypeAttributes::Convention'
16:17:48                                                        conv.ClangTypeLoc);
16:17:48                                                        ~~~~ ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2189:21: error: no member named 'ClangTypeLoc' in 'swift::TypeAttributes::Convention'; did you mean 'ClangType'?
16:17:48       diagnose(conv.ClangTypeLoc, diag::unable_to_parse_c_function_type,
16:17:48                     ^~~~~~~~~~~~
16:17:48                     ClangType
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/Attr.h:73:24: note: 'ClangType' declared here
16:17:48     Located<StringRef> ClangType = Located<StringRef>(StringRef(), {});
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:1782:20: error: no matching member function for call to 'diagnose'
16:17:48       return diags.diagnose(std::forward<ArgTypes>(Args)...);
16:17:48              ~~~~~~^~~~~~~~
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2177:7: note: in instantiation of function template specialization '(anonymous namespace)::TypeResolver::diagnose<swift::Located<llvm::StringRef> &, swift::Diag<llvm::StringRef, llvm::StringRef> &, llvm::StringRef &, swift::Located<llvm::StringRef> &>' requested here
16:17:48       diagnose(conv.ClangTypeLoc,
16:17:48       ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:837:5: note: candidate function template not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'swift::SourceLoc' for 1st argument
16:17:48     diagnose(SourceLoc Loc, Diag<ArgTypes...> ID,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:859:5: note: candidate function template not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'swift::DeclNameLoc' for 1st argument
16:17:48     diagnose(DeclNameLoc Loc, Diag<ArgTypes...> ID,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:910:5: note: candidate function template not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'const swift::Decl *' for 1st argument
16:17:48     diagnose(const Decl *decl, Diag<ArgTypes...> id,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:845:5: note: candidate template ignored: could not match 'Diag' against 'Located'
16:17:48     diagnose(Diag<ArgTypes...> ID,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:787:24: note: candidate function not viable: requires 3 arguments, but 4 were provided
16:17:48     InFlightDiagnostic diagnose(SourceLoc Loc, DiagID ID, 
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:805:24: note: candidate function not viable: requires 3 arguments, but 4 were provided
16:17:48     InFlightDiagnostic diagnose(DeclNameLoc Loc, DiagID ID, 
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:877:24: note: candidate function not viable: requires 3 arguments, but 4 were provided
16:17:48     InFlightDiagnostic diagnose(const Decl *decl, DiagID id,
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:819:24: note: candidate function not viable: requires 2 arguments, but 4 were provided
16:17:48     InFlightDiagnostic diagnose(SourceLoc Loc, const Diagnostic &D) {
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:892:24: note: candidate function not viable: requires 2 arguments, but 4 were provided
16:17:48     InFlightDiagnostic diagnose(const Decl *decl, const Diagnostic &diag) {
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:1782:20: error: no matching member function for call to 'diagnose'
16:17:48       return diags.diagnose(std::forward<ArgTypes>(Args)...);
16:17:48              ~~~~~~^~~~~~~~
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/lib/Sema/TypeCheckType.cpp:2189:7: note: in instantiation of function template specialization '(anonymous namespace)::TypeResolver::diagnose<swift::Located<llvm::StringRef> &, swift::Diag<llvm::StringRef> &, swift::Located<llvm::StringRef> &>' requested here
16:17:48       diagnose(conv.ClangTypeLoc, diag::unable_to_parse_c_function_type,
16:17:48       ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:837:5: note: candidate function template not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'swift::SourceLoc' for 1st argument
16:17:48     diagnose(SourceLoc Loc, Diag<ArgTypes...> ID,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:859:5: note: candidate function template not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'swift::DeclNameLoc' for 1st argument
16:17:48     diagnose(DeclNameLoc Loc, Diag<ArgTypes...> ID,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:910:5: note: candidate function template not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'const swift::Decl *' for 1st argument
16:17:48     diagnose(const Decl *decl, Diag<ArgTypes...> id,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:787:24: note: candidate function not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'swift::SourceLoc' for 1st argument
16:17:48     InFlightDiagnostic diagnose(SourceLoc Loc, DiagID ID, 
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:805:24: note: candidate function not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'swift::DeclNameLoc' for 1st argument
16:17:48     InFlightDiagnostic diagnose(DeclNameLoc Loc, DiagID ID, 
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:877:24: note: candidate function not viable: no known conversion from 'swift::Located<llvm::StringRef>' to 'const swift::Decl *' for 1st argument
16:17:48     InFlightDiagnostic diagnose(const Decl *decl, DiagID id,
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:845:5: note: candidate template ignored: could not match 'Diag' against 'Located'
16:17:48     diagnose(Diag<ArgTypes...> ID,
16:17:48     ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:819:24: note: candidate function not viable: requires 2 arguments, but 3 were provided
16:17:48     InFlightDiagnostic diagnose(SourceLoc Loc, const Diagnostic &D) {
16:17:48                        ^
16:17:48 /Users/buildnode/jenkins/workspace/swift-PR-osx-smoke-test/branch-master/swift/include/swift/AST/DiagnosticEngine.h:892:24: note: candidate function not viable: requires 2 arguments, but 3 were provided
16:17:48     InFlightDiagnostic diagnose(const Decl *decl, const Diagnostic &diag) {
16:17:48                        ^
16:17:48 7 errors generated.

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2020

Build failed
Swift Test OS X Platform
Git Sha - 040050a

@compnerd
Copy link
Member Author

compnerd commented Jan 7, 2020

Please test with following PRs:
#29033

@swift-ci please smoke test macOS platform

@compnerd
Copy link
Member Author

compnerd commented Jan 7, 2020

@swift-ci please smoke test

@compnerd compnerd merged commit 3d102b6 into swiftlang:master Jan 7, 2020
@compnerd compnerd deleted the 28737 branch January 7, 2020 04:11
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.

3 participants