Rust: détecter quand des "paramètres de type sans contrainte" peuvent être fournis explicitement à un appel fn

Créé le 21 févr. 2017  ·  3Commentaires  ·  Source: rust-lang/rust

En nous basant sur https://github.com/rust-lang/rust/pull/39361 , nous voudrons peut-être déterminer quand les utilisateurs doivent ajouter des paramètres de type explicites à un appel fn. J'imagine un exemple comme celui-ci :

fn foo<T>() { }

fn main() {
    foo();
}

Ce serait bien de suggérer à l'utilisateur d'écrire foo::<T> pour un T explicite. Cela demandera un peu de réflexion :

Quand voulons-nous suggérer cela de préférence à l'annotation d'une variable locale ? Je préférerais attacher l'annotation sur la variable locale, mais peut-être pas si le type de la variable locale est quelque chose de complexe qui mentionne le type non inféré profondément à l'intérieur, alors qu'annoter la fonction nous permettrait de spécifier le type non inféré directement .

Un exemple:

fn foo<T>() -> Option<T> { }

fn main() {
    let x = foo();
}

Devrions-nous suggérer d'étiqueter x: Option<T> ou foo::<T> ? Ce cas est limite, mais si vous remplacez Option par un type plus complexe, cela fait encore pencher la balance.

Que fait-on quand le fn prend plusieurs types, et qu'on les connaît partiellement ? Nous avons évité le problème avant de savoir quoi faire lorsque nous avons quelques informations mais pas toutes. Mais on dirait qu'ici, c'est peut-être plus important. Un exemple:

fn foo<T, U>() -> T { }

fn main() {
    let x: i32 = foo();
}

Ici, nous connaissons T , mais pas U . Devrions-nous suggérer foo::<_, XXX> ? Comment formulons-nous le XXX pour indiquer à l'utilisateur que c'est ce qu'il doit fournir ?

cc @cengizIO -- intéressant à poursuivre ?

cc @estebank @jonathandturner -- réflexions sur la façon de formuler ?

A-diagnostics C-enhancement E-needs-mentor T-compiler WG-compiler-errors

Commentaire le plus utile

Sortie courant :

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required

Quelques options :

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required
   = note: generic parameter `U` needs to be specified for foo::<T, U>()
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |                  |
   |                  you can specify the generic parameter here using `foo::<_, U>()`
   |
   = note: generic parameter `U` needs to be specified for `fn foo::<T, U>() -> T`
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U` in `fn foo<T, U>() -> T`
   |                  |
   |                  specify `U` using `foo::<_, U>()`
   |

Tous les 3 commentaires

Bonjour @nikomatsakis

Je vais travailler dessus.

Merci encore!

Sortie courant :

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required

Quelques options :

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required
   = note: generic parameter `U` needs to be specified for foo::<T, U>()
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |                  |
   |                  you can specify the generic parameter here using `foo::<_, U>()`
   |
   = note: generic parameter `U` needs to be specified for `fn foo::<T, U>() -> T`
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U` in `fn foo<T, U>() -> T`
   |                  |
   |                  specify `U` using `foo::<_, U>()`
   |

Cette note en particulier me glace les yeux :

   = note: type annotations or generic parameter binding required

Enlevons définitivement celui-là. :)

Cette page vous a été utile?
0 / 5 - 0 notes