This is a good point to consider on its own. While I agree with the mental model that injection should result in "pasting" the contents into the enclosing context, given the different late-parsing behavior you describe, a user would get the following behavior, which probably won’t quite seem like pasting:
Code in question:
using namespace std::experimental;
struct A1 {
struct B {};
B b = D(); //works
B getB() { return D(); } //works
struct D : B {};
};
struct A2 {
struct B {};
consteval {
-> fragment struct {
B b = D(); //error
B getB() { return D(); } //error
};
}
struct D : B {};
};
Perhaps a better way to put it is that model is that an executing metaprogram is just like *parsing* the contained declarations into the enclosed context, after resolving any dependencies. Parsing into a class does two things: 1. adds the essential content of the declarations immediately, and 2. defers parsing of the non-essentials until the closing brace of the outermost enclosing class. Evaluation of a metaprogram should probably result in both distinct effects as well.
Circling back on this with fresh eyes... those errors are right. Injection *does* work that way. Things that would be deferred in a normal parse a deferred for injection also.
But these are errors because metaprograms are not parsed in the complete class context of A2 -- it's not deferred. Also, the class context of the fragment is different than that of A2/ It's more like a local class in an inline member function (at least I hope that's the right analogy).