[glsl-in] Fix function lookup

First look for exact matches before trying the implicit
lookup. Otherwise, finding two wrong matches first will
result in an ambiguous function error.

This logic could use with a bit of a cleanup, keeping
track of a closer score and doing more exact matching
on types, but this might be good enough for now.
This commit is contained in:
Jasper St. Pierre
2021-06-26 10:46:23 -07:00
committed by João Capucho
parent 57b3256020
commit 8729391e53
2 changed files with 36 additions and 4 deletions

View File

@@ -507,6 +507,7 @@ impl Program<'_> {
})?;
let mut maybe_decl = None;
let mut ambiguous = false;
'outer: for decl in declarations {
if args.len() != decl.parameters.len() {
@@ -538,17 +539,22 @@ impl Program<'_> {
if exact {
maybe_decl = Some(decl);
ambiguous = false;
break;
} else if maybe_decl.is_some() {
return Err(ErrorKind::SemanticError(
meta,
format!("Ambiguous best function for '{}'", name).into(),
));
ambiguous = true;
} else {
maybe_decl = Some(decl)
}
}
if ambiguous {
return Err(ErrorKind::SemanticError(
meta,
format!("Ambiguous best function for '{}'", name).into(),
));
}
let decl = maybe_decl.ok_or_else(|| {
ErrorKind::SemanticError(
meta,

View File

@@ -463,6 +463,32 @@ fn constants() {
assert!(constants.next().is_none());
}
#[test]
fn function_overloading() {
let mut entry_points = crate::FastHashMap::default();
entry_points.insert("".to_string(), ShaderStage::Vertex);
parse_program(
r#"
# version 450
float saturate(float v) { return clamp(v, 0.0, 1.0); }
vec2 saturate(vec2 v) { return clamp(v, vec2(0.0), vec2(1.0)); }
vec3 saturate(vec3 v) { return clamp(v, vec3(0.0), vec3(1.0)); }
vec4 saturate(vec4 v) { return clamp(v, vec4(0.0), vec4(1.0)); }
void main() {
float v1 = saturate(1.5);
vec2 v2 = saturate(vec2(0.5, 1.5));
vec3 v3 = saturate(vec3(0.5, 1.5, 2.5));
vec3 v4 = saturate(vec4(0.5, 1.5, 2.5, 3.5));
}
"#,
&entry_points,
)
.unwrap();
}
#[test]
fn implicit_conversions() {
let mut entry_points = crate::FastHashMap::default();