2797. Trait precondition violations

Section: 21.3.3 [meta.type.synop] Status: Resolved Submitter: Russia Opened: 2016-11-09 Last modified: 2018-11-12 04:30:58 UTC

Priority: 2

View other active issues in [meta.type.synop].

View all other issues in [meta.type.synop].

View all issues with Resolved status.

Discussion:

Addresses RU 2

Failed prerequirement for the type trait must result in ill-formed program. Otherwise hard detectable errors will happen:

#include <type_traits>

struct foo;

void damage_type_trait() {
  // must be ill-formed
  std::is_constructible<foo, foo>::value;
}

struct foo{};

int main() {
  static_assert(
    // produces invalid result
    std::is_constructible<foo, foo>::value,
    "foo must be constructible from foo"
  );
}

Suggested resolution:

Add to the end of the [meta.type.synop] section:

Program is ill-formed if precondition for the type trait is violated.

[2016-11-09, Jonathan provides wording]

[Issues Telecon 16-Dec-2016]

Priority 2

[2017-03-02, Daniel comments]

LWG 2939 has been created to signal that some of our current type trait constraints are not quite correct and I recommend not to enforce the required diagnostics for traits that are sensitive to mismatches of the current approximate rules.

[2017-03-03, Kona Friday morning]

Unanimous consent to adopt this for C++17, but due to a misunderstanding, it wasn't on the ballot

Setting status to 'Ready' so we'll get it in immediately post-C++17

[2017-06-15 request from Daniel]

I don't believe that this should be "Ready"; I added the extra note to LWG 2797 *and* added the new issue 2939 exactly to *prevent* 2797 being accepted for C++17

Setting status back to 'Open'

[2018-08 Batavia Monday issue discussion]

Issues 2797, 2939, 3022, and 3099 are all closely related. Walter to write a paper resolving them.

[2018-11-11 Resolved by P1285R0, adopted in San Diego.]

Proposed resolution:

This wording is relative to N4606.

  1. Add a new paragraph after 21.3.5.4 [meta.unary.prop] paragraph 3:

    -?- If an instantiation of any template declared in this subclause fails to meet the preconditions, the program is ill-formed.

  2. Change the specification for alignment_of in Table 39 in 21.3.6 [meta.unary.prop.query]:

    Table 39 — Type property queries
    template <class T> struct alignment_of; alignof(T).
    Requires: alignof(T) shall be a valid expression (5.3.6), otherwise the program is ill-formed
  3. Change the specification for is_base_of, is_convertible, is_callable, and is_nothrow_callable in Table 40 in 21.3.7 [meta.rel]:

    Table 40 — Type relationship predicates
    […]
    template <class Base, class
    Derived>
    struct is_base_of;
    […] If Base and Derived are
    non-union class types and are
    different types (ignoring possible
    cv-qualifiers) then Derived shall
    be a complete type, otherwise the program is ill-formed.
    [Note: Base classes that
    are private, protected, or ambiguous are,
    nonetheless, base classes. — end note]
    template <class From, class To>
    struct is_convertible;
    see below From and To shall be complete
    types, arrays of unknown bound,
    or (possibly cv-qualified) void
    types, otherwise the program is
    ill-formed
    .
    template <class Fn, class...
    ArgTypes, class R>
    struct is_callable<
    Fn(ArgTypes...), R>;
    […] Fn, R, and all types in the
    parameter pack ArgTypes shall
    be complete types, (possibly
    cv-qualified) void, or arrays of
    unknown bound,
    otherwise the program is ill-formed
    .
    template <class Fn, class...
    ArgTypes, class R>
    struct is_nothrow_callable<
    Fn(ArgTypes...), R>;
    […] Fn, R, and all types in the
    parameter pack ArgTypes shall
    be complete types, (possibly
    cv-qualified) void, or arrays of
    unknown bound,
    otherwise the program is ill-formed
    .
  4. Add a new paragraph after 21.3.8 [meta.trans] paragraph 2:

    -2- Each of the templates in this subclause shall be a TransformationTrait (20.15.1).

    -?- If an instantiation of any template declared in this subclause fails to meet the Requires: preconditions, the program is ill-formed.