Interpolate strings by desugaring to Str.concat

We could definitely make this more efficent by
allocating enough space for the final string
and then copying the contents of each of the pieces
into it one by one. We don't do that yet though!
This commit is contained in:
Richard Feldman 2020-08-31 23:09:57 -04:00
parent 2e15443c8c
commit 37a254cef3
5 changed files with 60 additions and 96 deletions

View file

@ -1,4 +1,4 @@
use crate::builtins::{empty_list_type, float_literal, int_literal, list_type};
use crate::builtins::{empty_list_type, float_literal, int_literal, list_type, str_type};
use crate::pattern::{constrain_pattern, PatternState};
use roc_can::annotation::IntroducedVariables;
use roc_can::constraint::Constraint::{self, *};
@ -199,35 +199,7 @@ pub fn constrain_expr(
exists(vars, And(cons))
}
Str(segments) => {
use crate::builtins::str_type;
use roc_can::expr::StrSegment::*;
let mut cons = Vec::with_capacity(segments.len() + 1);
let expect_interpolated =
|region| Expected::ForReason(Reason::StrInterpolation, str_type(), region);
for segment in segments {
match segment {
Plaintext(_) => {
// Plaintext strings add no constraints
}
Interpolation(loc_expr) => {
cons.push(constrain_expr(
env,
loc_expr.region,
&loc_expr.value,
expect_interpolated(loc_expr.region),
));
}
}
}
// The expression as a whole should have the type Str.
cons.push(Eq(str_type(), expected, Category::Str, region));
And(cons)
}
Str(_) => Eq(str_type(), expected, Category::Str, region),
List {
elem_var,
loc_elems,