cplusplus / cplusplus/draft

[expr.await] lacks the specification for overload "operator co_await"

Open
#5,208 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TeX
Stars
221
Forks
813
Avg merge
16h 4m
Merged PRs (30d)
36

Description

[over.oper.general] says

The co_­await operator is described completely in [expr.await]. The attributes and restrictions found in the rest of [over.oper] do not apply to it unless explicitly stated in [expr.await].

we only mention operator co_await operator in [expr.await] p3

Evaluation of an await-expression involves the following auxiliary types, expressions, and objects:

  • [...]
  • o is determined by enumerating the applicable operator co_­await functions for an argument a ([over.match.oper]), and choosing the best one through overload resolution ([over.match]). If overload resolution is ambiguous, the program is ill-formed. If no viable functions are found, o is a. Otherwise, o is a call to the selected function with the argument a. If o would be a prvalue, the temporary materialization conversion ([conv.rval]) is applied.

Except that, we didn't mention operator co_await in [expr.await] any more. In the complete subclause [expr.await], we never give the specification that which scopes an operator co_await can be declared in, what number of parameters the function shall have, and how the lookup rules perform to find the function. We never state these details in [expr.await].

struct Awaiter{
    bool await_ready(){return false;}
    void await_suspend(std::coroutine_handle<>){}
    void await_resume(){}
};
struct CoroutineType{
    struct promise_type;
    using handle = std::coroutine_handle<promise_type>;
    struct promise_type{
        auto initial_suspend(){
            return std::suspend_always{};
        }
        auto final_suspend() noexcept{
            return std::suspend_always{};
        }
        auto get_return_object(){
            return CoroutineType{handle::from_promise(*this)};
        }
        void unhandled_exception(){

        }
    };
    handle coro;
};

// contrast 1
struct C{
    Awaiter operator co_await(){return Awaiter{};}
};
CoroutineType fun(){
    co_await C{};
} 

// contrast 2
struct D{};
Awaiter operator co_await(D){
   return Awaiter{};
}

CoroutineType  fun2(){
   co_await  D{};
}

// contrast 3
namespace X{
    struct ADL{};
    Awaiter operator co_await(ADL){
        return Awaiter{};
    }
}
CoroutineType fun3(){
    co_await X::ADL{};
}

By testing the implementations(e.g., Clang and GCC), it seems that having a different scope in which operator co_await is declared, the function should accompany by a different number of parameters. As well, a different lookup rule will perform to find the declarations.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing [expr.await] p3 with the statement in [over.oper.general], then examine the three example declarations and the reported Clang and GCC behavior. Determine the intended specification for declaration scopes, parameter counts, and lookup rules for operator co_await; the issue is done when these details are stated consistently in [expr.await].

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.