non credo che questo sia un errore, anche se sembra confusa, ma è solo il modo in cui il compilatore compila il valore sopra vincolante.
Sezione 14.6.3 afferma che se la definizione del valore non è un singolo modello di valore (come è il caso qui), l'espressione elaborato è
tmp <typars1… typarsn> = expr
ident1 <typars1> = expr1
…
identn <typarsn> = exprn
dove tmp è un identificatore fresco e ogni risultato expri da la compilazione del pattern pat (§7) contro input tmp [da spec].
vedere ciò che il compilatore fa, potremmo usare un # citazione F, ad esempio:
<@ let test (x:int, {A = x:int})= x in test (3, {A = 5}) @>;;
In formato stringa vengo (lasciando un po 'di roba):
Let (test,
Lambda (tupledArg,
Let (x, TupleGet (tupledArg, 0),
Let (_arg1, TupleGet (tupledArg, 1),
Let (x, PropertyGet (Some (_arg1), A, []), x)))),
Application (test, NewTuple (Value (3), NewRecord (foo, Value (5)))))
che è per questo che prendi la "inner" x.
Non penso che sia un bug ma forse sarebbe più coerente se questo generasse un avvertimento.
Esempio più semplice - 'let test (x, (x, y)) = 1' –
Non sono sicuro del motivo per cui questa domanda ha avuto un downvote - mi sembra un problema interessante! Penso che questo sia un bug e puoi segnalarlo inviando email a _fsbugs_ a _microsoft_ dot _com_. –
Non sono sicuro se si tratta di un bug - è probabilmente seguendo le seguenti regole di scoping vincolando alla x definita più vicina. – plinth