Skip to content

Commit fd7fa1b

Browse files
committed
Tighten covariance rules wrt. in params with -preview=in
Require the `in` storage class on both sides, just like ref/out/lazy. Doing so makes sure the code compiles with all compilers and for all targets, independent from whether `in` means `const scope` or `const scope ref`.
1 parent a7e0d3d commit fd7fa1b

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

src/dmd/mtype.d

+4-4
Original file line numberDiff line numberDiff line change
@@ -6900,8 +6900,8 @@ extern (C++) final class Parameter : ASTNode
69006900
* Params:
69016901
* returnByRef = true if the function returns by ref
69026902
* p = Parameter to compare with
6903-
* previewIn = Whether `-previewIn` is being used, and thus if
6904-
* `in` means `scope`.
6903+
* previewIn = Whether `-preview=in` is being used, and thus if
6904+
* `in` means `scope [ref]`.
69056905
*
69066906
* Returns:
69076907
* true = `this` can be used in place of `p`
@@ -6921,8 +6921,8 @@ extern (C++) final class Parameter : ASTNode
69216921
otherSTC |= STC.scope_;
69226922
}
69236923

6924-
enum stc = STC.ref_ | STC.out_ | STC.lazy_;
6925-
if ((thisSTC & stc) != (otherSTC & stc))
6924+
const mask = STC.ref_ | STC.out_ | STC.lazy_ | (previewIn ? STC.in_ : 0);
6925+
if ((thisSTC & mask) != (otherSTC & mask))
69266926
return false;
69276927
return isCovariantScope(returnByRef, thisSTC, otherSTC);
69286928
}

src/dmd/mtype.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ class Parameter : public ASTNode
558558
static size_t dim(Parameters *parameters);
559559
static Parameter *getNth(Parameters *parameters, d_size_t nth);
560560
const char *toChars() const;
561-
bool isCovariant(bool returnByRef, const Parameter *p) const;
561+
bool isCovariant(bool returnByRef, const Parameter *p, bool previewIn) const;
562562
};
563563

564564
struct ParameterList

test/compilable/previewin.d

+9-6
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ struct FooBar
2424
string toString() const
2525
{
2626
string result;
27+
// Type is const
28+
this.toString((in char[] buf) {
29+
static assert(is(typeof(buf) == const(char[])));
30+
result ~= buf;
31+
});
2732
// Type inference works
28-
this.toString((buf) { result ~= buf; });
29-
// Specifying the STC too
3033
this.toString((in buf) { result ~= buf; });
31-
// Some covariance
32-
this.toString((const scope buf) { result ~= buf; });
33-
this.toString((scope const(char)[] buf) { result ~= buf; });
34-
this.toString((scope const(char[]) buf) { result ~= buf; });
34+
// No covariance without explicit `in`
35+
static assert(!__traits(compiles, { this.toString((buf) { result ~= buf; }); }));
36+
static assert(!__traits(compiles, { this.toString((const scope buf) { result ~= buf; }); }));
37+
static assert(!__traits(compiles, { this.toString((const scope ref buf) { result ~= buf; }); }));
3538
return result;
3639
}
3740

0 commit comments

Comments
 (0)