@@ -30,6 +30,7 @@ import dmd.expression;
3030import dmd.expressionsem;
3131import dmd.func;
3232import dmd.funcsem;
33+ import dmd.globals : global;
3334import dmd.hdrgen;
3435import dmd.id;
3536import dmd.identifier;
@@ -292,8 +293,9 @@ Expression opOverloadUnary(UnaExp e, Scope* sc)
292293 // For ++ and --, rewrites to += and -= are also tried, so don't error yet
293294 if (! e.isPreExp())
294295 {
295- error(e.loc, " operator `%s` is not defined for `%s`" , EXPtoString(e.op).ptr, ad.toErrMsg());
296- errorSupplemental(ad.loc, " perhaps overload the operator with `auto opUnary(string op : \" %s\" )() {}`" ,
296+ auto eSink = global.errorSink;
297+ eSink.error(e.loc, " operator `%s` is not defined for `%s`" , EXPtoString(e.op).ptr, ad.toErrMsg());
298+ eSink.errorSupplemental(ad.loc, " perhaps overload the operator with `auto opUnary(string op : \" %s\" )() {}`" ,
297299 EXPtoString(e.op).ptr);
298300 return ErrorExp.get ();
299301 }
@@ -385,8 +387,10 @@ Expression opOverloadArray(ArrayExp ae, Scope* sc)
385387 if (ae2.isErrorExp())
386388 {
387389 if (! e0 && ! search_function(ad, Id.dollar))
388- ad.loc.errorSupplemental(" perhaps define `opDollar` for `%s`" , ad.toChars());
389-
390+ {
391+ auto eSink = global.errorSink;
392+ eSink.errorSupplemental(ad.loc, " perhaps define `opDollar` for `%s`" , ad.toChars());
393+ }
390394 return ae2;
391395 }
392396 /* Rewrite a[i..j] as:
@@ -512,7 +516,8 @@ Expression binAliasThis(BinExp e, Scope* sc, Type[2] aliasThisStop)
512516 }
513517 if (rewrittenLhs)
514518 {
515- error(e.loc, " cannot use `alias this` to partially initialize variable `%s` of type `%s`. Use `%s`" ,
519+ auto eSink = global.errorSink;
520+ eSink.error(e.loc, " cannot use `alias this` to partially initialize variable `%s` of type `%s`. Use `%s`" ,
516521 e.e1.toErrMsg(), ad1.toErrMsg(), rewrittenLhs.toErrMsg());
517522 return ErrorExp.get ();
518523 }
@@ -551,6 +556,8 @@ Expression opOverloadBinary(BinExp e, Scope* sc, Type[2] aliasThisStop)
551556 if (Expression err = binSemanticProp(e, sc))
552557 return err;
553558
559+ auto eSink = global.errorSink;
560+
554561 AggregateDeclaration ad1 = isAggregate(e.e1.type);
555562 AggregateDeclaration ad2 = isAggregate(e.e2.type);
556563
@@ -559,14 +566,14 @@ Expression opOverloadBinary(BinExp e, Scope* sc, Type[2] aliasThisStop)
559566
560567 if (s && ! (s.isTemplateDeclaration() || s.isOverloadSet))
561568 {
562- error(e.e1.loc, " `%s.opBinary` isn't a template" , e.e1.toErrMsg());
569+ eSink. error(e.e1.loc, " `%s.opBinary` isn't a template" , e.e1.toErrMsg());
563570 return ErrorExp.get ();
564571 }
565572
566573 Dsymbol s_r = search_function(ad2, Id.opBinaryRight);
567574 if (s_r && ! (s_r.isTemplateDeclaration() || s_r.isOverloadSet()))
568575 {
569- error(e.e2.loc, " `%s.opBinaryRight` isn't a template" , e.e2.toErrMsg());
576+ eSink. error(e.e2.loc, " `%s.opBinaryRight` isn't a template" , e.e2.toErrMsg());
570577 return ErrorExp.get ();
571578 }
572579 if (s_r && s_r == s) // https://issues.dlang.org/show_bug.cgi?id=12778
@@ -591,6 +598,8 @@ bool suggestBinaryOverloads(BinExp e, Scope* sc)
591598 if (! e.op.hasOpBinary)
592599 return false ;
593600
601+ auto eSink = global.errorSink;
602+
594603 AggregateDeclaration ad1 = isAggregate(e.e1.type);
595604 AggregateDeclaration ad2 = isAggregate(e.e2.type);
596605
@@ -600,23 +609,23 @@ bool suggestBinaryOverloads(BinExp e, Scope* sc)
600609 {
601610 // This expressionSemantic will fail, otherwise operator overloading would have succeeded before
602611 dotTemplateCall(e.e1, Id.opBinary, opToArg(sc, e.op), e.e2).expressionSemantic(sc);
603- errorSupplemental(s.loc, " `opBinary` defined here" );
612+ eSink. errorSupplemental(s.loc, " `opBinary` defined here" );
604613 return true ;
605614 }
606- error(e.loc, " operator `%s` is not defined for type `%s`" , EXPtoString(e.op).ptr, e.e1.type.toChars);
607- errorSupplemental(ad1.loc, " perhaps overload the operator with `auto opBinary(string op : \" %s\" )(%s rhs) {}`" , EXPtoString(e.op).ptr, e.e2.type.toChars);
615+ eSink. error(e.loc, " operator `%s` is not defined for type `%s`" , EXPtoString(e.op).ptr, e.e1.type.toChars);
616+ eSink. errorSupplemental(ad1.loc, " perhaps overload the operator with `auto opBinary(string op : \" %s\" )(%s rhs) {}`" , EXPtoString(e.op).ptr, e.e2.type.toChars);
608617 return true ;
609618 }
610619 else if (ad2)
611620 {
612621 if (Dsymbol s_r = search_function(ad1, Id.opBinaryRight))
613622 {
614623 dotTemplateCall(e.e2, Id.opBinaryRight, opToArg(sc, e.op), e.e1).expressionSemantic(sc);
615- errorSupplemental(s_r.loc, " `opBinaryRight` defined here" );
624+ eSink. errorSupplemental(s_r.loc, " `opBinaryRight` defined here" );
616625 return true ;
617626 }
618- error(e.loc, " operator `%s` is not defined for type `%s`" , EXPtoString(e.op).ptr, e.e2.type.toChars);
619- errorSupplemental(ad2.loc, " perhaps overload the operator with `auto opBinaryRight(string op : \" %s\" )(%s lhs) {}`" , EXPtoString(e.op).ptr, e.e1.type.toChars);
627+ eSink. error(e.loc, " operator `%s` is not defined for type `%s`" , EXPtoString(e.op).ptr, e.e2.type.toChars);
628+ eSink. errorSupplemental(ad2.loc, " perhaps overload the operator with `auto opBinaryRight(string op : \" %s\" )(%s lhs) {}`" , EXPtoString(e.op).ptr, e.e1.type.toChars);
620629 return true ;
621630 }
622631 return false ;
@@ -636,10 +645,12 @@ bool suggestOpOpAssign(BinAssignExp exp, Scope* sc, Expression parent)
636645 if (! ad)
637646 return false ;
638647
648+ auto eSink = global.errorSink;
649+
639650 if (parent && (parent.isPreExp() || parent.isPostExp()))
640651 {
641- error(exp.loc, " operator `%s` not supported for `%s` of type `%s`" , EXPtoString(parent.op).ptr, exp.e1.toErrMsg(), ad.toErrMsg());
642- errorSupplemental(ad.loc,
652+ eSink. error(exp.loc, " operator `%s` not supported for `%s` of type `%s`" , EXPtoString(parent.op).ptr, exp.e1.toErrMsg(), ad.toErrMsg());
653+ eSink. errorSupplemental(ad.loc,
643654 " perhaps implement `auto opUnary(string op : \" %s\" )() {}`" ~
644655 " or `auto opOpAssign(string op : \" %s\" )(int) {}`" ,
645656 EXPtoString(stripAssignOp(parent.op)).ptr,
@@ -655,8 +666,8 @@ bool suggestOpOpAssign(BinAssignExp exp, Scope* sc, Expression parent)
655666 }
656667 else
657668 {
658- error(exp.loc, " operator `%s` not supported for `%s` of type `%s`" , EXPtoString(exp.op).ptr, exp.e1.toErrMsg(), ad.toErrMsg());
659- errorSupplemental(ad.loc, " perhaps implement `auto opOpAssign(string op : \" %s\" )(%s) {}`" ,
669+ eSink. error(exp.loc, " operator `%s` not supported for `%s` of type `%s`" , EXPtoString(exp.op).ptr, exp.e1.toErrMsg(), ad.toErrMsg());
670+ eSink. errorSupplemental(ad.loc, " perhaps implement `auto opOpAssign(string op : \" %s\" )(%s) {}`" ,
660671 EXPtoString(stripAssignOp(exp.op)).ptr, exp.e2.type.toChars());
661672 }
662673 return true ;
@@ -675,6 +686,8 @@ private Expression dotTemplateCall(Expression e, Identifier id, Objects* tiargs,
675686
676687Expression opOverloadEqual (EqualExp e, Scope* sc, Type[2 ] aliasThisStop)
677688{
689+ auto eSink = global.errorSink;
690+
678691 Type t1 = e.e1.type.toBasetype();
679692 Type t2 = e.e2.type.toBasetype();
680693
@@ -692,7 +705,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
692705 if (t1.isTypeClass() && e.e2.isNullExp() ||
693706 t2.isTypeClass() && e.e1.isNullExp())
694707 {
695- error(e.loc, " use `%s` instead of `%s` when comparing with `null`" ,
708+ eSink. error(e.loc, " use `%s` instead of `%s` when comparing with `null`" ,
696709 EXPtoString(e.op == EXP .equal ? EXP .identity : EXP .notIdentity).ptr,
697710 EXPtoString(e.op).ptr);
698711 return ErrorExp.get ();
@@ -717,7 +730,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
717730 */
718731 if (! ClassDeclaration.object)
719732 {
720- error(e.loc, " cannot compare classes for equality because `object.Object` was not declared" );
733+ eSink. error(e.loc, " cannot compare classes for equality because `object.Object` was not declared" );
721734 return null ;
722735 }
723736
@@ -821,7 +834,7 @@ Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
821834 size_t dim = tup1.exps.length;
822835 if (dim != tup2.exps.length)
823836 {
824- error(e.loc, " mismatched sequence lengths, `%d` and `%d`" ,
837+ eSink. error(e.loc, " mismatched sequence lengths, `%d` and `%d`" ,
825838 cast (int )dim, cast (int )tup2.exps.length);
826839 return ErrorExp.get ();
827840 }
@@ -867,7 +880,8 @@ Expression opOverloadCmp(CmpExp exp, Scope* sc, Type[2] aliasThisStop)
867880
868881 if (! e.type.isScalar() && e.type.equals(exp.e1.type))
869882 {
870- error(e.loc, " recursive `opCmp` expansion" );
883+ auto eSink = global.errorSink;
884+ eSink.error(e.loc, " recursive `opCmp` expansion" );
871885 return ErrorExp.get ();
872886 }
873887 if (! e.isCallExp())
@@ -1016,7 +1030,8 @@ Expression opOverloadBinaryAssign(BinAssignExp e, Scope* sc, Type[2] aliasThisSt
10161030 Dsymbol s = search_function(ad1, Id.opOpAssign);
10171031 if (s && ! (s.isTemplateDeclaration() || s.isOverloadSet()))
10181032 {
1019- error(e.loc, " `%s.opOpAssign` isn't a template" , e.e1.toErrMsg());
1033+ auto eSink = global.errorSink;
1034+ eSink.error(e.loc, " `%s.opOpAssign` isn't a template" , e.e1.toErrMsg());
10201035 return ErrorExp.get ();
10211036 }
10221037
@@ -1088,9 +1103,10 @@ private Expression pickBestBinaryOverload(Scope* sc, Objects* tiargs, Dsymbol s,
10881103 if (! (m.lastf == lastf && m.count == 2 && count == 1 ))
10891104 {
10901105 // Error, ambiguous
1091- error(e.loc, " overloads `%s` and `%s` both match argument list for `%s`" , m.lastf.type.toErrMsg(), m.nextf.type.toErrMsg(), m.lastf.toErrMsg());
1092- errorSupplemental(m.lastf.loc, " `%s` is declared here" , m.lastf.toPrettyChars());
1093- errorSupplemental(m.nextf.loc, " `%s` is declared here" , m.nextf.toPrettyChars());
1106+ auto eSink = global.errorSink;
1107+ eSink.error(e.loc, " overloads `%s` and `%s` both match argument list for `%s`" , m.lastf.type.toErrMsg(), m.nextf.type.toErrMsg(), m.lastf.toErrMsg());
1108+ eSink.errorSupplemental(m.lastf.loc, " `%s` is declared here" , m.lastf.toPrettyChars());
1109+ eSink.errorSupplemental(m.nextf.loc, " `%s` is declared here" , m.nextf.toPrettyChars());
10941110 }
10951111 }
10961112 else if (m.last == MATCH .nomatch)
@@ -1156,9 +1172,10 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, ref EXP
11561172
11571173 Expression suggestOverloading (Expression other, AggregateDeclaration ad)
11581174 {
1159- error(e.loc, " no operator `%s` for type `%s`" , EXPtoString(e.op).ptr, ad.toChars);
1175+ auto eSink = global.errorSink;
1176+ eSink.error(e.loc, " no operator `%s` for type `%s`" , EXPtoString(e.op).ptr, ad.toChars);
11601177 string op = e.isEqualExp() ? " bool" : " int" ;
1161- errorSupplemental(ad.loc, " perhaps overload it with `%.*s %s(%s other) const {}`" , op.fTuple.expand, id.toChars, other.type.toChars);
1178+ eSink. errorSupplemental(ad.loc, " perhaps overload it with `%.*s %s(%s other) const {}`" , op.fTuple.expand, id.toChars, other.type.toChars);
11621179 return ErrorExp.get ();
11631180 }
11641181
@@ -1536,10 +1553,11 @@ private FuncDeclaration findBestOpApplyMatch(Expression ethis, FuncDeclaration f
15361553
15371554 if (fd_ambig)
15381555 {
1539- .error(ethis.loc, " `%s.%s` matches more than one declaration:" ,
1556+ auto eSink = global.errorSink;
1557+ eSink.error(ethis.loc, " `%s.%s` matches more than one declaration:" ,
15401558 ethis.toErrMsg(), fstart.ident.toErrMsg());
1541- .errorSupplemental(fd_best.loc, " `%s`\n and:" , fd_best.type.toChars());
1542- .errorSupplemental(fd_ambig.loc, " `%s`" , fd_ambig.type.toChars());
1559+ eSink .errorSupplemental(fd_best.loc, " `%s`\n and:" , fd_best.type.toChars());
1560+ eSink .errorSupplemental(fd_ambig.loc, " `%s`" , fd_ambig.type.toChars());
15431561 return null ;
15441562 }
15451563
0 commit comments