mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-14 07:29:02 +03:00
force interpolated variables to be of type string
This commit is contained in:
parent
fec42d8654
commit
21b540751a
@ -2600,10 +2600,38 @@ fn flatten_str_lines<'a>(
|
|||||||
fn desugar_str_segments(var_store: &mut VarStore, segments: Vec<StrSegment>) -> Expr {
|
fn desugar_str_segments(var_store: &mut VarStore, segments: Vec<StrSegment>) -> Expr {
|
||||||
use StrSegment::*;
|
use StrSegment::*;
|
||||||
|
|
||||||
|
let n = segments.len();
|
||||||
let mut iter = segments.into_iter().rev();
|
let mut iter = segments.into_iter().rev();
|
||||||
let mut loc_expr = match iter.next() {
|
let mut loc_expr = match iter.next() {
|
||||||
Some(Plaintext(string)) => Loc::at(Region::zero(), Expr::Str(string)),
|
Some(Plaintext(string)) => Loc::at(Region::zero(), Expr::Str(string)),
|
||||||
Some(Interpolation(loc_expr)) => loc_expr,
|
Some(Interpolation(loc_expr)) => {
|
||||||
|
if n == 1 {
|
||||||
|
// We concat with the empty string to ensure a type error when loc_expr is not a string
|
||||||
|
let empty_string = Loc::at(Region::zero(), Expr::Str("".into()));
|
||||||
|
|
||||||
|
let fn_expr = Loc::at(
|
||||||
|
Region::zero(),
|
||||||
|
Expr::Var(Symbol::STR_CONCAT, var_store.fresh()),
|
||||||
|
);
|
||||||
|
let expr = Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
var_store.fresh(),
|
||||||
|
fn_expr,
|
||||||
|
var_store.fresh(),
|
||||||
|
var_store.fresh(),
|
||||||
|
)),
|
||||||
|
vec![
|
||||||
|
(var_store.fresh(), empty_string),
|
||||||
|
(var_store.fresh(), loc_expr),
|
||||||
|
],
|
||||||
|
CalledVia::StringInterpolation,
|
||||||
|
);
|
||||||
|
|
||||||
|
Loc::at(Region::zero(), expr)
|
||||||
|
} else {
|
||||||
|
loc_expr
|
||||||
|
}
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
// No segments? Empty string!
|
// No segments? Empty string!
|
||||||
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
procedure Str.3 (#Attr.2, #Attr.3):
|
||||||
|
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||||
|
ret Str.251;
|
||||||
|
|
||||||
procedure Test.1 (Test.5):
|
procedure Test.1 (Test.5):
|
||||||
let Test.16 : [C {}, C U64, C Str] = TagId(0) Test.5;
|
let Test.16 : [C {}, C U64, C Str] = TagId(0) Test.5;
|
||||||
ret Test.16;
|
ret Test.16;
|
||||||
|
|
||||||
procedure Test.1 (Test.5):
|
procedure Test.1 (Test.5):
|
||||||
let Test.30 : [C {}, C U64, C Str] = TagId(1) Test.5;
|
let Test.31 : [C {}, C U64, C Str] = TagId(1) Test.5;
|
||||||
ret Test.30;
|
ret Test.31;
|
||||||
|
|
||||||
procedure Test.2 (Test.7):
|
procedure Test.2 (Test.7):
|
||||||
let Test.23 : [C {}, C U64, C Str] = TagId(2) Test.7;
|
let Test.23 : [C {}, C U64, C Str] = TagId(2) Test.7;
|
||||||
@ -16,13 +20,16 @@ procedure Test.6 (Test.17, #Attr.12):
|
|||||||
ret Test.19;
|
ret Test.19;
|
||||||
|
|
||||||
procedure Test.6 (Test.17, #Attr.12):
|
procedure Test.6 (Test.17, #Attr.12):
|
||||||
let Test.34 : U64 = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
let Test.35 : U64 = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||||
let Test.33 : Str = "";
|
let Test.34 : Str = "";
|
||||||
ret Test.33;
|
ret Test.34;
|
||||||
|
|
||||||
procedure Test.8 (Test.24, #Attr.12):
|
procedure Test.8 (Test.24, #Attr.12):
|
||||||
let Test.27 : Str = UnionAtIndex (Id 2) (Index 0) #Attr.12;
|
let Test.28 : Str = UnionAtIndex (Id 2) (Index 0) #Attr.12;
|
||||||
ret Test.27;
|
let Test.27 : Str = "";
|
||||||
|
let Test.26 : Str = CallByName Str.3 Test.27 Test.28;
|
||||||
|
dec Test.28;
|
||||||
|
ret Test.26;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.3 : U8 = 0u8;
|
let Test.3 : U8 = 0u8;
|
||||||
@ -55,7 +62,7 @@ procedure Test.0 ():
|
|||||||
jump Test.13 Test.21;
|
jump Test.13 Test.21;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
let Test.29 : U64 = 1i64;
|
let Test.30 : U64 = 1i64;
|
||||||
let Test.28 : [C {}, C U64, C Str] = CallByName Test.1 Test.29;
|
let Test.29 : [C {}, C U64, C Str] = CallByName Test.1 Test.30;
|
||||||
jump Test.13 Test.28;
|
jump Test.13 Test.29;
|
||||||
|
|
||||||
|
@ -813,6 +813,32 @@ fn list_get_negative_index() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "wasm"))] // TODO: mismatch is due to terminal control codes!
|
||||||
|
#[test]
|
||||||
|
fn invalid_string_interpolation() {
|
||||||
|
expect_failure(
|
||||||
|
"\"$(123)\"",
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
── TYPE MISMATCH ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
This argument to this string interpolation has an unexpected type:
|
||||||
|
|
||||||
|
4│ "$(123)"
|
||||||
|
^^^
|
||||||
|
|
||||||
|
The argument is a number of type:
|
||||||
|
|
||||||
|
Num *
|
||||||
|
|
||||||
|
But this string interpolation needs its argument to be:
|
||||||
|
|
||||||
|
Str
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn issue_2149_i8_ok() {
|
fn issue_2149_i8_ok() {
|
||||||
expect_success(r#"Str.toI8 "127""#, "Ok 127 : Result I8 [InvalidNumStr]");
|
expect_success(r#"Str.toI8 "127""#, "Ok 127 : Result I8 [InvalidNumStr]");
|
||||||
|
Loading…
Reference in New Issue
Block a user