@@ -61,8 +61,8 @@ class SwiftDispatcher {
6161 // This method gives a TRAP label for already emitted AST node.
6262 // If the AST node was not emitted yet, then the emission is dispatched to a corresponding
6363 // visitor (see `visit(T *)` methods below).
64- template <typename E>
65- TrapLabelOf<E> fetchLabel (E* e) {
64+ template <typename E, typename ... Args >
65+ TrapLabelOf<E> fetchLabel (E* e, Args&&... args ) {
6666 assert (e && " trying to fetch a label on nullptr, maybe fetchOptionalLabel is to be used?" );
6767 // this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might
6868 // end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel`
@@ -73,7 +73,7 @@ class SwiftDispatcher {
7373 return *l;
7474 }
7575 waitingForNewLabel = e;
76- visit (e);
76+ visit (e, std::forward<Args>(args)... );
7777 // TODO when everything is moved to structured C++ classes, this should be moved to createEntry
7878 if (auto l = store.get (e)) {
7979 if constexpr (!std::is_base_of_v<swift::TypeBase, E>) {
@@ -168,10 +168,10 @@ class SwiftDispatcher {
168168 // return `std::optional(fetchLabel(arg))` if arg converts to true, otherwise std::nullopt
169169 // universal reference `Arg&&` is used to catch both temporary and non-const references, not
170170 // for perfect forwarding
171- template <typename Arg>
172- auto fetchOptionalLabel (Arg&& arg) -> std::optional<decltype(fetchLabel(arg))> {
171+ template <typename Arg, typename ... Args >
172+ auto fetchOptionalLabel (Arg&& arg, Args&&... args ) -> std::optional<decltype(fetchLabel(arg))> {
173173 if (arg) {
174- return fetchLabel (arg);
174+ return fetchLabel (arg, std::forward<Args>(args)... );
175175 }
176176 return std::nullopt ;
177177 }
@@ -263,9 +263,15 @@ class SwiftDispatcher {
263263
264264 template <typename Tag, typename T, typename ... Ts>
265265 bool fetchLabelFromUnionCase (const llvm::PointerUnion<Ts...> u, TrapLabel<Tag>& output) {
266- if (auto e = u.template dyn_cast <T>()) {
267- output = fetchLabel (e);
268- return true ;
266+ // we rely on the fact that when we extract `ASTNode` instances (which only happens
267+ // on `BraceStmt` elements), we cannot encounter a standalone `TypeRepr` there, so we skip
268+ // this case; extracting `TypeRepr`s here would be problematic as we would not be able to
269+ // provide the corresponding type
270+ if constexpr (!std::is_same_v<T, swift::TypeRepr*>) {
271+ if (auto e = u.template dyn_cast <T>()) {
272+ output = fetchLabel (e);
273+ return true ;
274+ }
269275 }
270276 return false ;
271277 }
@@ -294,7 +300,7 @@ class SwiftDispatcher {
294300 virtual void visit (swift::CaseLabelItem* item) = 0;
295301 virtual void visit (swift::Expr* expr) = 0;
296302 virtual void visit (swift::Pattern* pattern) = 0;
297- virtual void visit (swift::TypeRepr* type) = 0;
303+ virtual void visit (swift::TypeRepr* typeRepr, swift::Type type) = 0;
298304 virtual void visit (swift::TypeBase* type) = 0;
299305
300306 const swift::SourceManager& sourceManager;
0 commit comments