www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5666] New: std.array.replace compile error (string and immutable string)

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666

           Summary: std.array.replace compile error (string and immutable
                    string)
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: d_lang ku6.jp



Code
----
import std.array;

void main()
{
    immutable string r = "de";
    replace("abcde", "abc", r);
}
----

Compile error
----
test.d(6): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) does not match any
function template declaration
test.d(6): Error: template std.array.replace(T,Range) if
(isDynamicArray!(Range) && is(ElementType!(Range) : T)) cannot deduce template
function from argument types !()(string,string,immutable(char[]))
----

dmd version is 2.052.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 28 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |jmdavisProg gmx.com
         Resolution|                            |INVALID



PST ---
Of course that doesn't compile. Think about it for a moment. r is an
_immutable_ string. It _cannot_ change. Not only cannot you not alter any of
its elements (since the elements are immutable), but the reference itself is
immutable, so it can't be reassigned to another string. replace takes a
reference to the string that you pass it, creates a new string with the
replacement made in it, and then assigns the result to the original reference.
That won't work if the original is immutable. And in this case, it is. So, this
is not a bug. It is as designed. If you want to be able to use replace, you
need to do it on a mutable string (the elements can be immutable - a string is
immutable(char)[] after all - but the reference must be mutable).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666




PST ---
Of wait. I read that code wrong. I read it like it was

replace(r, "to be replaced", "to replace with");

Regardless, it's still wrong. As I said, replace takes a reference to a string
- notice that its signature has ref on its first parameter. You passed it a
temporary - the string literal "abcde". ref parameters _must_ refer to an
actual variable, not a temporary.

So, this is still invalid. I just gave the wrong reason. Sorry about that.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666




Sorry. My description was so bad.

I want use 'R1 replace(R1, R2, R3)(R1 subject, R2 from, R3 to)' replacement for
std.string.replace.

----
import std.array;

void main()
{
    string r = "de";
    string replaced = replace("abcde", "abc", r);
}
---
This code is no problem.


----
import std.array;

void main()
{
    immutable string r = "de";
    string replaced = replace("abcde", "abc", r);
}
---
But, this code is failed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |
           Severity|normal                      |enhancement



PST ---
Ah, okay. I relooked at the code, at that version of replace _should_ be
returning a new string instead of making the changes in place (it's the one
which takes indices which makes the changes in place). The problem is still
that you're giving it an immutable string. replace takes a range for its last 2
arguments. Normally, immutable ranges are useless. You can't pop their front
(because they're immutable), and sometimes you can't even get their front,
because their front property isn't const or immutable. So, in the general case,
passing an immutable range to a function just doesn't work. The current
template constraints for std.array.replace reflect that.

However, arrays are a bit funny in that the compiler understands that you can
get away with copying an array without altering its immutable original, so it's
legal to take an immutable array (or string) and pass it to a function which
takes an array with immutable elements but a mutable array (so it could have a
paramater of string and yet take an immutable string). So, the template
constraint _could_ be adjusted to allow for immutable arrays, even though it
couldn't take immutable ranges which _aren't_ arrays.

So, I'll reopen this an enhancement. However, I would point out that you
probably don't want to be in the habit of using immutable ranges. While it does
sometimes work with arrays, since the compiler understands them and lets them
get away with some stuff that normal types can't, in the general case,
immutable ranges are pretty much useless.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666


Rainer Schuetze <r.sagitario gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |r.sagitario gmx.de



PST ---
Very much related is this issue with join in dmd 2.052:

import std.string;

void main()
{
    string[] a = ["1","2","3"];
    join(a,std.string.newline);
}

test.d(6): Error: template std.array.join(RoR,R) if (isInputRange!(RoR) &&
isInputRange!(ElementType!(RoR)) && isForwardRange!(R)) does not match any
function template declaration
test.d(6): Error: template std.array.join(RoR,R) if (isInputRange!(RoR) &&
isInputRange!(ElementType!(RoR)) && isForwardRange!(R)) cannot deduce template
function from argument types !()(string[],immutable(char[2u]))

This worked in 2.051, aswell as the code with replace in the original report.

I consider these regressions, because the functions should just work with
immutable string arguments. The user should not be bothered with the internals
of the implementation of these functions. IIRC the regression happened because
both functions are now based on ranges in std.array, whereas there were some
special string implementations in std.string before.

The new implementations would probably work if creating a copy of a value of
type "immutable char[]" (as done when passing a function argument to
replace/join) would allow implicite conversion to immutable(char)[].

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666


kennytm gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kennytm gmail.com
         OS/Version|Windows                     |All



std.array.join doesn't work with array of const/immutable string either :\

------------------------
import std.array;
void main() {
    const(char[])[] d;
    join(d, ",");
}
------------------------
x.d(5): Error: template std.array.join(RoR,R) if (isInputRange!(RoR) &&
isInputRange!(ElementType!(RoR)) && isForwardRange!(R)) does not match any
function template declaration
x.d(5): Error: template std.array.join(RoR,R) if (isInputRange!(RoR) &&
isInputRange!(ElementType!(RoR)) && isForwardRange!(R)) cannot deduce template
function from argument types !()(const(char[])[],string)
------------------------

It works if 'd' is a 'const(char)[][]'.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 04 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |ASSIGNED
                 CC|                            |andrei metalanguage.com
         AssignedTo|nobody puremagic.com        |andrei metalanguage.com


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 04 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666




PST ---
All of the test cases work with current git-head, but the last. I am not sure
if it isn't a restriction of join to not allow mixing modifiers.

I wonder why this issue is marked as an enhancement, I think it is a regression
in dmd 2.052.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 21 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5666


Andrei Alexandrescu <andrei erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|                            |FIXED



PST ---
Seems to have been fixed a while ago.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 08 2013