Is it allowed to reuse storage of a non-static data member and if so under what conditions?
Consider the program
#include<new>
#include<type_traits>
using T = /*some type*/;
using U = /*some type*/;
static_assert(std::is_object_v<T>);
static_assert(std::is_object_v<U>);
static_assert(sizeof(U) <= sizeof(T));
static_assert(alignof(U) <= alignof(T));
struct A {
    T t /*initializer*/;
    U* u;
    A() {
        t.~T();
        u = ::new(static_cast<void*>(&t)) U /*initializer*/;
    }
    ~A() {
        u->~U();
        ::new(static_cast<void*>(&t)) T /*initializer*/;
    }
    A(const A&) = delete;
    A(A&&) = delete;
    A& operator=(const A&) = delete;
    A& operator=(A&&) = delete;
};
int main() {
    auto a = new A;
    *(a->u) = /*some assignment*/;
    delete a; /*optional*/
    A b; /*alternative*/
    *(b.u) = /*some assignment*/; /*alternative*/
}
What conditions do object types T and U need to satisfy in addition to the static_asserts, so that the program has defined behavior, if any?
Does it depend on the destructor of A actually being called (e.g. on whether the /*optional*/ or /*alternative*/ lines are present)?.
Does it depend on the storage duration of A, e.g. whether /*alternative*/ lines in main are used instead?
Note that the program does not use the t member after the placement-new, except in the destructor. Of course using it while its storage is occupied by a different type is not allowed.
Please also note that I do not encourage anyone to write code like that. My intention is to understand details of the language better. In particular I did not find anything forbidding such placement-news as long as the destructor is not called, at least.
See also my other question regarding a modified version that does not execute the placement-news during construction/destruction of the enclosing object, since that seems to have caused complications according to some comments.
Concrete example as requested in comments demonstrating the wider question for a subset of types that I think represent different cases of interest:
#include<new>
#include<type_traits>
struct non_trivial {
    ~non_trivial() {};
};
template<typename T, bool>
struct S {
    T t{};
    S& operator=(const S&) { return *this; }
};
template<bool B>
using Q = S<int, B>; // alternatively S<const int, B> or S<non_trivial, B>
using T = Q<true>;
using U = Q<false>;
static_assert(std::is_object_v<T>);
static_assert(std::is_object_v<U>);
static_assert(sizeof(U) <= sizeof(T));
static_assert(alignof(U) <= alignof(T));
struct A {
    T t;
    U* u;
    A() {
        t.~T();
        u = ::new(static_cast<void*>(&t)) U;
    }
    ~A() {
        u->~U();
        ::new(static_cast<void*>(&t)) T;
    }
    A(const A&) = delete;
    A(A&&) = delete;
    A& operator=(const A&) = delete;
    A& operator=(A&&) = delete;
};
int main() {
    auto a = new A;
    *(a->u) = {};
    delete a; /*optional*/
    // A b; /*alternative*/
    // *(b.u) = {}; /*alternative*/
}