Rust: detectar quando "parâmetros de tipo irrestrito" podem ser fornecidos explicitamente para uma chamada fn

Criado em 21 fev. 2017  ·  3Comentários  ·  Fonte: rust-lang/rust

Com base em https://github.com/rust-lang/rust/pull/39361 , podemos considerar quando os usuários devem adicionar parâmetros de tipo explícitos a uma chamada fn. Estou imaginando um exemplo assim:

fn foo<T>() { }

fn main() {
    foo();
}

Seria bom sugerir que o usuário escrevesse foo::<T> para algum T explícito. Isso exigirá um pouco de reflexão:

Quando queremos sugerir isso em vez de anotar uma variável local? Eu preferiria anexar a anotação na variável local, mas talvez não se o tipo da variável local for alguma coisa complexa que mencione o tipo não inferido profundamente dentro dela, enquanto anotar a função nos permitiria especificar o tipo não inferido diretamente .

Um exemplo:

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

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

Devemos sugerir rotular x: Option<T> ou foo::<T> ? Este caso é limítrofe, mas se você substituir Option por algum tipo mais complexo, isso inclina ainda mais o equilíbrio.

O que fazemos quando o fn aceita muitos tipos e os conhecemos parcialmente? Evitamos o problema antes do que fazer quando temos algumas informações, mas não todas. Mas parece que aqui pode ser mais importante. Um exemplo:

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

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

Aqui sabemos T , mas não U . Devemos sugerir foo::<_, XXX> ? Como expressamos o XXX para indicar ao usuário que isso é o que ele precisa fornecer?

cc @cengizIO -- interessante em perseguir?

cc @estebank @jonathandturner -- pensamentos sobre como expressar?

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

Comentários muito úteis

Saída de corrente:

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

Algumas opções:

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>()`
   |

Todos 3 comentários

Olá @nikomatsakis

Estarei trabalhando nisso.

Obrigado novamente!

Saída de corrente:

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

Algumas opções:

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>()`
   |

Esta nota em particular faz meus olhos brilharem:

   = note: type annotations or generic parameter binding required

Vamos definitivamente remover esse. :)

Esta página foi útil?
0 / 5 - 0 avaliações