David Peter 2 years ago
parent
commit
86df7f3fd8

+ 1 - 0
examples/name_resolution_error/unit_clashes_with_parameter.nbt

@@ -0,0 +1 @@
+fn foo(t: Time) -> Scalar = t / hour

+ 3 - 0
examples/name_resolution_error/variable_clashes_with_parameter.nbt

@@ -0,0 +1,3 @@
+let foo = 2
+
+fn bar(foo: Scalar) -> Scalar = foo

+ 3 - 3
examples/numbat_syntax.nbt

@@ -55,9 +55,9 @@ let y3: Length / Time = 2 m/s      # more complex type annotation
 
 # 5. Function definitions
 
-fn foo(x: Scalar) -> Scalar = 2 * x + 3         # A simple function
-fn speed(s: Length, t: Time) -> Speed = s / t   # Two parameters
-fn my_sqrt<T>(x: T^2) -> T = x^(1/2)            # A generic function
+fn foo(z: Scalar) -> Scalar = 2 * z + 3                 # A simple function
+fn speed(len: Length, dur: Time) -> Speed = len / dur   # Two parameters
+fn my_sqrt<T>(q: T^2) -> T = q^(1/2)                    # A generic function
 
 # 6. Dimension definitions
 

+ 16 - 0
numbat/src/prefix_transformer.rs

@@ -158,6 +158,22 @@ impl Transformer {
                 self.function_names.push(function_name.clone());
                 self.prefix_parser
                     .add_other_identifier(&function_name, function_name_span)?;
+
+                // We create a clone of the full transformer for the purpose
+                // of checking/transforming the function body. The reason for this
+                // is that we don't want the parameter names to pollute the global
+                // namespace. But we need to register parameter names as identifiers
+                // because they could otherwise shadow global identifiers:
+                //
+                //   fn foo(t: Time) -> Time = t    # not okay: shadows 't' for ton
+                //
+                let mut fn_body_transformer = self.clone();
+                for (param_span, param, _, _) in &parameters {
+                    fn_body_transformer
+                        .prefix_parser
+                        .add_other_identifier(&param, param_span.clone())?;
+                }
+
                 Statement::DefineFunction {
                     function_name_span,
                     function_name,