<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>233384</bug_id>
          
          <creation_ts>2021-11-19 14:36:11 -0800</creation_ts>
          <short_desc>Ref&lt;T&gt; should support indirection operator *</short_desc>
          <delta_ts>2022-02-17 01:50:06 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>Web Template Framework</component>
          <version>Other</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>WONTFIX</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Jean-Yves Avenard [:jya]">jean-yves.avenard</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>achristensen</cc>
    
    <cc>cdumez</cc>
    
    <cc>darin</cc>
    
    <cc>ggaren</cc>
    
    <cc>koivisto</cc>
    
    <cc>mark.lam</cc>
    
    <cc>rniwa</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>ysuzuki</cc>
    
    <cc>zalan</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1817002</commentid>
    <comment_count>0</comment_count>
    <who name="Jean-Yves Avenard [:jya]">jean-yves.avenard</who>
    <bug_when>2021-11-19 14:36:11 -0800</bug_when>
    <thetext>While Ref&lt;T&gt; was supposed to be a replacement for T&amp; with lifetime guarantees, C++ limitations made it act more like a pointer than a reference.
Ref&lt;T&gt; is more like a RefPtr&lt;T&gt; that guarantees it&apos;s never null.

A Ref can be converted into a RefPtr directly.
You already have to dereference the content of a Ref&lt;T&gt; using operator-&gt;().

So it makes sense that it also implements the indirection operator *.

I propose that Ref&lt;T&gt; be made to at the very least support the indirection operator and maybe even be officially be made into just a RefPtr that guarantees to never be null (so get() would return T* rather than T&amp;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817029</commentid>
    <comment_count>1</comment_count>
    <who name="Alex Christensen">achristensen</who>
    <bug_when>2021-11-19 15:36:58 -0800</bug_when>
    <thetext>To me, the indirection operator is used when you have something that might be null/nullopt/error, so you check if (thing) { useThing(*thing); } but that isn&apos;t the case with Ref.  It never needs checking whether it&apos;s null because if you haven&apos;t used it after you moved from it, it&apos;s never null.  Adding the indirection operator would make it so when we write code that just calls useThing(*thing), we now have to think about whether it is a Ref or not.  Also, when someone down the line changes thing from a Ref to a RefPtr, we would then have code that may not be nearby that needs a null check, but you didn&apos;t notice it because it compiled fine.  This really needs operator dot, but C++ doesn&apos;t allow that.  It currently follows the convention of unique_ptr&lt;T&gt;::get which returns a T*, but it returns a T&amp;.

Maybe we could implement Ref&lt;T&gt;::operator&amp; instead of Ref&lt;T&gt;::ptr to get a T*, though.  That would be nicer syntactically.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817030</commentid>
    <comment_count>2</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2021-11-19 15:46:06 -0800</bug_when>
    <thetext>Jean-Yves mentioned on Slack that supporting operator*() would make converting from RefPtr&lt;T&gt; to Ref&lt;T&gt; easier.

Alex seems to be pointing out that supporting operator*() would make converting from Ref&lt;T&gt; to RefPtr&lt;T&gt; harder / more error-prone.

It seems like the logic here is the same: There&apos;s an impedance mismatch because Ref&lt;T&gt;  offers more than RefPtr&lt;T&gt;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817070</commentid>
    <comment_count>3</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2021-11-19 20:42:25 -0800</bug_when>
    <thetext>I&apos;m pretty this is an intentional design choice because we wanted it to act like a reference. This is why Ref has operator T&amp; whereas RefPtr doesn&apos;t, and Ref::get returns T&amp; instead of T* as in RefPtr::get. To get a pointer, you call Ref::ptr instead.

I actually don&apos;t understand why we want operator *. Why would operator T&amp; not be sufficient?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817075</commentid>
    <comment_count>4</comment_count>
    <who name="Jean-Yves Avenard [:jya]">jean-yves.avenard</who>
    <bug_when>2021-11-19 21:53:13 -0800</bug_when>
    <thetext>(In reply to Ryosuke Niwa from comment #3)
&gt; I&apos;m pretty this is an intentional design choice because we wanted it to act
&gt; like a reference. 

Indeed that was the intent, but the lack of operator.() in C++ makes it that you have to use -&gt; to dereference it; as such, in practice it works like a pointer.

&gt; I actually don&apos;t understand why we want operator *. Why would operator T&amp;
&gt; not be sufficient?

Yes, Alex made a good point there.

As Geoffrey mentioned, currently there&apos;s a mismatch between intent and actual usage.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817085</commentid>
    <comment_count>5</comment_count>
    <who name="Antti Koivisto">koivisto</who>
    <bug_when>2021-11-19 23:16:08 -0800</bug_when>
    <thetext>Originally Ref had just get() (since operator.() doesn&apos;t exist in C++). It was considered too verbose so operator-&gt;() was added as a somewhat inconsistent workaround. This doesn&apos;t mean it should have pointer-like semantics in general.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817092</commentid>
    <comment_count>6</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2021-11-20 00:04:52 -0800</bug_when>
    <thetext>(In reply to Jean-Yves Avenard [:jya] from comment #4)
&gt; (In reply to Ryosuke Niwa from comment #3)
&gt; &gt; I&apos;m pretty this is an intentional design choice because we wanted it to act
&gt; &gt; like a reference. 
&gt; 
&gt; Indeed that was the intent, but the lack of operator.() in C++ makes it that
&gt; you have to use -&gt; to dereference it; as such, in practice it works like a
&gt; pointer.

Just because the presence of operator-&gt; doesn&apos;t make it a pointer like. Ref::operator! works like T::operator! so it&apos;s not pointer-like in that regard for example. In fact, almost everything else doesn&apos;t behave like a pointer.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1817093</commentid>
    <comment_count>7</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2021-11-20 00:05:07 -0800</bug_when>
    <thetext>FWIW, I&apos;m opposed to the proposed change.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1818002</commentid>
    <comment_count>8</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2021-11-26 14:37:25 -0800</bug_when>
    <thetext>&lt;rdar://problem/85773648&gt;</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>