-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[PlaygroundTransform] Disable logging ~Copyable
types as they can’t be passed to the generic logging function
#71293
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
[PlaygroundTransform] Disable logging ~Copyable
types as they can’t be passed to the generic logging function
#71293
Conversation
@swift-ci please test windows platform |
@swift-ci please smoke test |
…layground Transform, as such types are not supported in generics yet.
…Playground Transform.
ad61364
to
af5f647
Compare
@swift-ci please test windows platform |
@swift-ci please smoke test |
@swift-ci please test windows platform |
lib/Sema/PlaygroundTransform.cpp
Outdated
@@ -786,6 +799,14 @@ class Instrumenter : InstrumenterBase { | |||
return std::make_pair(PBD, VD); | |||
} | |||
|
|||
bool shouldLogType(Type Ty) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe generalize this over ASTNode
instead i.e. shouldLog(ASTNode)
so that you can cast to ValueDecl *
internally to get its interface type?
bool shouldLog(ASTNode node) {
if (auto *VD = node.dyn_cast<ValueDecl *>())
return VD->hasInterfaceType() ? !VD->getInterfaceType()->isNoncopyable() : true;
if (auto *E = node.dyn_cast<Expr *>())
return !E->getType()->isNoncopyable();
return true;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this change and the CI is failing with:
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: error: implicit instantiation of undefined template 'llvm::FirstIndexOfType<swift::ValueDecl *>'
: std::integral_constant<size_t, 1 + FirstIndexOfType<T, Us...>::value> {};
^
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: note: in instantiation of template class 'llvm::FirstIndexOfType<swift::ValueDecl *, swift::CaseLabelItem *>' requested here
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: note: in instantiation of template class 'llvm::FirstIndexOfType<swift::ValueDecl *, swift::StmtConditionElement *, swift::CaseLabelItem *>' requested here
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: note: in instantiation of template class 'llvm::FirstIndexOfType<swift::ValueDecl *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>' requested here
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: note: in instantiation of template class 'llvm::FirstIndexOfType<swift::ValueDecl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>' requested here
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: note: in instantiation of template class 'llvm::FirstIndexOfType<swift::ValueDecl *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>' requested here
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/STLExtras.h:172:42: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:230:30: note: in instantiation of template class 'llvm::FirstIndexOfType<swift::ValueDecl *, swift::Expr *, swift::Stmt *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>' requested here
return F.Val.getInt() == FirstIndexOfType<To, PTs...>::value;
^
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:248:27: note: in instantiation of function template specialization 'llvm::CastInfoPointerUnionImpl<swift::Expr *, swift::Stmt *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>::isPossible<swift::ValueDecl *>' requested here
return Impl::template isPossible<To>(f);
^
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/Support/Casting.h:311:19: note: in instantiation of member function 'llvm::CastInfo<swift::ValueDecl *, llvm::PointerUnion<swift::Expr *, swift::Stmt *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>>::isPossible' requested here
if (!Derived::isPossible(f))
^
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/llvm-project/llvm/include/llvm/Support/Casting.h:406:23: note: in instantiation of member function 'llvm::DefaultDoCastIfPossible<swift::ValueDecl *, llvm::PointerUnion<swift::Expr *, swift::Stmt *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>, llvm::CastInfo<swift::ValueDecl *, llvm::PointerUnion<swift::Expr *, swift::Stmt *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>>>::doCastIfPossible' requested here
return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f));
^
/Users/ec2-user/jenkins/workspace/swift-PR-macos-smoke-test/branch-main/swift/lib/Sema/PlaygroundTransform.cpp:803:25: note: in instantiation of function template specialization 'llvm::PointerUnion<swift::Expr *, swift::Stmt *, swift::Decl *, swift::Pattern *, swift::TypeRepr *, swift::StmtConditionElement *, swift::CaseLabelItem *>::dyn_cast<swift::ValueDecl *>' requested here
if (auto *VD = node.dyn_cast<ValueDecl *>())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, it's union with a Decl *
so you need to do dyn_cast_or_null<ValueDecl>(node.dyn_cast<Decl *>())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Pavel, CI is green with this change now. Does the rest of the code look reasonable to you?
@swift-ci please smoke test |
03e769e
to
4d6284d
Compare
@swift-ci please smoke test |
@swift-ci please test windows platform |
1 similar comment
@swift-ci please test windows platform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good with one small note I left inline. Do you want to do the same for ~Escapable
?
lib/Sema/PlaygroundTransform.cpp
Outdated
@@ -686,6 +694,11 @@ class Instrumenter : InstrumenterBase { | |||
} else if (auto *MRE = dyn_cast<MemberRefExpr>(*RE)) { | |||
Expr *B = MRE->getBase(); | |||
ConcreteDeclRef M = MRE->getMember(); | |||
VarDecl *VD = cast<VarDecl>(M.getDecl()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need to do this, can pass M.getDecl()
to shouldLog
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, thanks! Removed.
4d6284d
to
e0cbc62
Compare
@swift-ci please smoke test |
Oh, we should definitely do that. I can address that in a separate PR. |
Sounds good to me! |
@swift-ci please smoke test |
1 similar comment
@swift-ci please smoke test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks @dbukowski!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please test with -enable-experimental-feature NoncopyableGenerics
lib/Sema/PlaygroundTransform.cpp
Outdated
@@ -786,6 +799,14 @@ class Instrumenter : InstrumenterBase { | |||
return std::make_pair(PBD, VD); | |||
} | |||
|
|||
bool shouldLogType(Type Ty) { | |||
// Don't try to log ~Copyable types, as we can't pass them to the generic logging functions yet. | |||
if (Ty->isNoncopyable()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can’t pass interface types to isNoncopyable(), it will assert once the noncopyable generics flag is on.
lib/Sema/PlaygroundTransform.cpp
Outdated
@@ -686,6 +694,11 @@ class Instrumenter : InstrumenterBase { | |||
} else if (auto *MRE = dyn_cast<MemberRefExpr>(*RE)) { | |||
Expr *B = MRE->getBase(); | |||
ConcreteDeclRef M = MRE->getMember(); | |||
VarDecl *VD = cast<VarDecl>(M.getDecl()); | |||
|
|||
if (!shouldLogType(VD->getInterfaceType())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use VD->getTypeInContext()
lib/Sema/PlaygroundTransform.cpp
Outdated
@@ -658,6 +658,10 @@ class Instrumenter : InstrumenterBase { | |||
// after or instead of the expression they're looking at. Only call this | |||
// if the variable has an initializer. | |||
Added<Stmt *> logVarDecl(VarDecl *VD) { | |||
if (!shouldLogType(VD->getInterfaceType())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VD-getTypeInContext()
lib/Sema/PlaygroundTransform.cpp
Outdated
@@ -674,6 +678,10 @@ class Instrumenter : InstrumenterBase { | |||
if (auto *DRE = dyn_cast<DeclRefExpr>(*RE)) { | |||
VarDecl *VD = cast<VarDecl>(DRE->getDecl()); | |||
|
|||
if (!shouldLogType(VD->getInterfaceType())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VD->getTypeInContext()
bool shouldLog(ASTNode node) { | ||
// Don't try to log ~Copyable types, as we can't pass them to the generic logging functions yet. | ||
if (auto *VD = dyn_cast_or_null<ValueDecl>(node.dyn_cast<Decl *>())) | ||
return VD->hasInterfaceType() ? !VD->getInterfaceType()->isNoncopyable() : true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t call hasInterfaceType(), it doesn’t do what you think it does (it means “have I computed the type yet” not “this has a type”)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Slava! Based on your comments, it sounds like shouldLog
should look something like this:
bool shouldLog(ASTNode node) {
// Don't try to log ~Copyable types, as we can't pass them to the generic logging functions yet.
if (auto *VD = dyn_cast_or_null<ValueDecl>(node.dyn_cast<Decl *>()))
return !VD->getTypeInContext()->isNoncopyable();
if (auto *E = node.dyn_cast<Expr *>())
return !E->getType()->isNoncopyable();
return true;
}
Does that look reasonable? Unfortunately, I have already merged this PR, so I would open a new one with the necessary changes (after testing with -enable-experimental-feature NoncopyableGenerics
as you suggested).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that looks good, thanks!
Summary
Xcode Playgrounds cannot execute code with
~Copyable
types, as the Playground Transform tries to pass them to the generic logging function, which is not supported yet. These changes disable logging them altogether for now, which can be reverted once generics start supporting move-only types. Another approach would be to introduce a placeholder log, which could be recognized by the clients in order to inform the user about the reason for the missing logs.Changes
shouldLogType(Type)
to check theisNoncopyable
flag and use it in all paths that can lead to creating a playground log.rdar://115035973