Iain, this is the second bug, also found in Folly and also not extracted to a testcase. We were ICEing because we ended up tsubst_copying something that had already been tsubst, leading to an assert failure (mostly such repeated tsubsting is harmless). We had a non-dependent co_await in a non-dependent-type template fn, so we processed it at definition time, and then reprocessed at instantiation time. This is not quite the right fix, as it'll make all co_awaits in a template function have dependent type. However, in practice it appears less ICEy! Exprs only have dependent type if at least one operand is dependent -- which was what you were trying to do. Coroutines have the additional wrinkle, that the current fn's type is an implicit operand. So, if the coroutine function's type is not dependent, and the operand is not dependent, we should determine the type of the co_await expression using the DEPENDENT_EXPR wrapper machinery. That allows us to determine the subexpression type, but leave its operand unchanged and then instantiate it later. I'm not sure if the std explicitly calls out this dependent-subexpr-type wrinkle. nathan -- Nathan Sidwell