v
v copied to clipboard
Use of $tmpl cannot be used as a function parameter
V 0.3.0 3bdf2f0
What did you do?
Attempted to return an HTML template by explicitly referring to it by name from a web handler:
return app.html($tmpl('index.html'))
What did you expect to see?
The rendered template.
What did you see instead?
The program fails to compile:
/tmp/v_1000/vvv.6869482243414842251.tmp.c:31972: error: identifier expected
Workaround
s := $tmpl('index.html')
return app.html(s)
Here's the generated line 31999 (the issue is the return _tmpl_res_login733
part):
vweb__Result _t2 = vweb__Context_html(&app->Context, return _tmpl_res_login733);
This should just be something like this (the return is removed):
vweb__Result _t2 = vweb__Context_html(&app->Context, _tmpl_res_login733);
It looks like the $tmpl
function / pragma / whatever that is is being blindly replaced with a return {template}
in the generated C, rather than taking its context into account.
V doctor
OS: linux, Linux version 5.18.7-200.fc36.x86_64 ([email protected]) (gcc (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1), GNU ld version 2.37-27.fc36) #1 SMP PREEMPT_DYNAMIC Sat Jun 25 20:06:14 UTC 2022 Processor: 12 cpus, 64bit, little endian, Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz CC version: cc (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1)
getwd: /home/chip vmodules: /home/chip/.vmodules vroot: /home/chip/bin vexe: /home/chip/bin/v vexe mtime: 2022-07-04 14:53:19 is vroot writable: true is vmodules writable: true V full version: V 0.3.0 eb10cc9.3bdf2f0
Git version: git version 2.36.1 Git vroot status: 0.3-28-g3bdf2f05 .git/config present: true thirdparty/tcc status: thirdparty-linux-amd64 827f7452
Full source
<!-- index.html -->
<html>
<head>
<title>V Test</title>
</head>
<body>
<form method="POST" action="/login">
<h1>Login</h1>
<input placeholder="email" type="email" name="email" />
<input placeholder="password" type="password" name="password" />
<button>Login</button>
</form>
</body>
</html>
// main.v
import vweb
struct App {
vweb.Context
}
fn main() {
vweb.run(&App{}, 3003)
}
[post]
fn (mut app App) login(email string, password string) vweb.Result {
if email == '[email protected]' && password == 'password' {
name := email.split('@')[0]
return app.redirect('/hello/$name')
}
// This is the offending line
return app.html($tmpl('index.html'))
}
['/']
fn (mut app App) index() vweb.Result {
return $vweb.html()
}
['/hello/:name']
fn (mut app App) hello_name(name string) vweb.Result {
return app.text('Hello, $name!')
}
$tmpl
is being replaced with other code at compile time so I don't think this is a bug. The $tmpl
function isn't executed at compile time so it is not replaced with a string value as you might think.
It seems to me that the workaround you found is the intended behaviour, as it also passes a string to app.html
. I think this should be more clarified in the docs.
at least, proper checker error message is needed.
Fixed by #16229.