Rust: Rastreamento de problema para RFC 2126: Esclareça e agilize caminhos e visibilidade

Criado em 17 set. 2017  ·  120Comentários  ·  Fonte: rust-lang/rust

Este é um problema de rastreamento para o RFC "Esclarecer e otimizar caminhos e visibilidade" (rust-lang / rfcs # 2126).

Degraus:

Perguntas não resolvidas:

  • Como devemos abordar a migração? Por meio de um fallback, conforme proposto, ou por meio de épocas? Provavelmente, é melhor fazer essa determinação com mais experiência, por exemplo, depois de termos uma ferramenta rustfix em mãos.

  • A sintaxe final para caminhos absolutos; há mais bicicletas a serem feitas aqui, em um contexto em que podemos realmente experimentar as várias opções. Em particular, existem algumas vantagens reais em ter os caminhos crate:: e extern:: , mas, idealmente, poderíamos fazer isso de uma forma mais sucinta.

B-RFC-approved C-tracking-issue E-needs-mentor T-lang WG-compiler-front

Comentários muito úteis

Aqui está outra instância que acabei de encontrar que combina a palavra-chave crate em um modificador de visibilidade e um caminho, que parece ainda mais provável do que a instância crate use crate... .

Atual:

pub(crate) struct Bar {
    pub(crate) foo: ::Foo,
}

pub(crate) struct Baz(pub(crate) ::Foo);

Com alterações deste problema de rastreamento:

crate struct Bar {
    crate foo: crate::Foo,
}

crate struct Baz(crate crate::Foo);

Eu pessoalmente acho o novo mais confuso do que o jeito atual.

Todos 120 comentários

Essa RFC tem 4 recursos distintos e ainda temos apenas um problema de rastreamento para todos eles. Podemos, por favor, não juntar recursos díspares como esse?

@ retep998 Conforme explicado ao longo das discussões RFC, esses recursos são conectados por meio de considerações de design global. Por exemplo, fornecer um mecanismo externo para renomear caixas é motivado em parte pela eventual depreciação de extern crate . Podemos e iremos bloquear vários aspectos separadamente (e provavelmente teremos algumas portas sobrepostas para experimentar sintaxes diferentes), mas para a discussão sobre o design geral e a estabilização, é importante manter a coerência global em mente.

Ter um mecanismo externo para renomear caixas é algo que já é desejado e necessário há anos (https://github.com/rust-lang/cargo/issues/1311) e poderia ter funcionado sozinho, mas está sendo usado como nada mais do que um peão para apoiar a eliminação de extern crate .

Não tivemos problemas em ter RFCs separados para recursos intimamente relacionados no passado (os RFCs para repr(align(N)) e repr(packed(N)) vêm à mente), mas agora estamos alegando que a alteração de foo/mod.rs a foo.rs está tão intimamente relacionado a extern:: e crate:: que eles têm que estar no mesmo RFC e usar o mesmo problema de rastreamento?

Apenas para garantir que este ponto permaneça, já que é um aspecto relativamente sutil da questão não resolvida de sintaxe: usar crate como um modificador de visibilidade, bem como um prefixo de caminho, introduz uma ambiguidade de análise entre crate ::absolute::path e crate::relative::path . Usar uma palavra-chave contextual apresenta a mesma ambiguidade e não há outras palavras-chave reservadas que realmente façam sentido como modificadores de visibilidade.

Assim, gostaria de (pelo menos) experimentar omitir o modificador de visibilidade crate e manter o pub(crate) .

Eu não me importaria de dividir o ponto foo.rs / foo/mod.rs em um problema de rastreamento separado, uma vez que ele realmente parece independente das alterações do modificador de caminho e visibilidade.

No que diz respeito à renomeação da caixa externa ... já existe um problema separado para isso? É muito importante que o caminho mude, então acho que é bom fazer parte deste também .

Apesar de muita discussão há algumas semanas sobre a escolha de crate como um modificador de visibilidade (não um prefixo de caminho), estou desapontado em ver que embora esta escolha de palavra-chave tenha sido listada como uma 'questão não resolvida' em o RFC, agora foi aparentemente esquecido. Eu mesmo, e vários outros que observei, acho essa escolha confusa, pois não é um adjetivo / modificador e também pode ser ambíguo: crate significa parte da API pública da caixa? Não! Significa local ou internal ou pub (lished) para a caixa (daí porque eu prefiro as últimas palavras-chave). Portanto, não estou exigindo mudanças imediatas, mas pelo menos reconheço isso como uma questão não resolvida neste problema de rastreamento, para que não seja esquecida na estabilização.

É ótimo que o redesenho deste módulo tenha progredido até agora, mas ao mesmo tempo é importante que não nos precipitemos apenas para fazer o 'período de implementação' e acabemos tomando decisões sem consultar a maioria dos usuários do Rust. E, infelizmente, acho que as pessoas envolvidas nas discussões de RFC do Github não são representativas de toda a base de usuários, por causa da enxurrada de informações / comentários / opiniões que pode ser desanimador. Então, de alguma forma, isso também precisa ser resolvido.

Não está claro como a implementação terminou ...

@rpjohnst @ retep998 Eu abri um novo RFC para discutir foo.rs + foo/ , bem como propor algumas melhorias para este RFC.

Editar: sugiro que abramos outro RFC para discutir crate como um modificador de visibilidade. Pessoalmente, gostaria de ver o oposto: pub(extern) ser adicionado e exigido para todos os símbolos publicados externamente. Isso faria com que pub fosse o equivalente a pub(crate) na próxima época.

@rpjohnst

introduz uma ambigüidade de análise entre crate :: absolute :: path e crate :: relative :: path

Não é crate ::relative::path um código inválido? Não pode ser rejeitado durante a análise?

@ est31 Não, isso requer resolução de nomes durante a análise, o que definitivamente não é algo que queremos fazer. É uma das partes mais irritantes da análise de C e C ++, que têm ambigüidades semelhantes em torno de a * b sendo uma multiplicação ou declaração e em torno de a b(c, d); sendo uma declaração de variável ou um protótipo de função.

Se começarmos a permitir dependências e módulos de nível superior com o mesmo nome, mesmo confundir a resolução de nomes com a análise não nos salvará- crate :: some :: item poderia ser um crate -visível item da dependência some , ou um item privado do módulo de nível superior some .

Para manter isso em perspectiva, poderíamos resolver arbitrariamente a ambigüidade de uma forma ou de outra e exigir que os parênteses escrevessem o outro caso (provavelmente o caso de caminho absoluto de visibilidade crate , que parece mais raro), mas isso ainda é um metralhadora de que não precisamos se ficar com pub(crate) , que já resolveu a ambigüidade sintática.

Usar crate como um modificador de visibilidade, bem como um prefixo de caminho, introduz uma ambigüidade de análise entre crate ::absolute::path e crate::relative::path .

Este é um pequeno problema, IMO, dado que ambas as visibilidades em campos de estrutura de tupla e caminhos absolutos "inline" são raros.
Os caminhos são sempre analisados ​​avidamente atualmente, então faz sentido para crate :: x :: y significar crate::x::y .
Se o significado oposto for desejado, então pub(crate) ::x::y ou crate (::x::y) podem ser usados.

@rpjohnst @petrochenkov poderia compartilhar um exemplo de código em que pub ::relative::path é um código válido? Não entendi toda a coisa da ambigüidade porque acho que um dos dois casos é inválido.

Editar: o único lugar onde isso pode ser relevante é dentro das macros quando você combina um qualificador de visibilidade + um caminho. Mas isso é uma quebra muito pequena tão aceitável IMO.

@ est31 Você parece ter uma ideia errada - não se trata de caminhos relativos, eles nunca são um problema. Trata-se de construir o AST antes de saber a que qualquer um dos nomes se refere. Aqui está um exemplo completo:

struct S(crate :: x :: y);

Visto que você ainda não tem permissão para pesquisar nenhum desses nomes, como converter essa sequência de caracteres em um AST? Há duas respostas possíveis. Um tem um campo privado de um tipo y definido no módulo x da caixa atual. O outro tem um campo visível crate de um tipo diferente y definido no nível superior de dependência x . Nenhuma macro necessária.

@rpjohnst vejo obrigado por esclarecer. É realmente uma ambigüidade.

@rpjohnst

Uma solução simples é defini-lo de forma inequívoca, analisando o modificador de visibilidade da caixa. Se você quiser analisá-lo como uma estrutura de tupla com membro privado do tipo fornecido, faça assim:

    struct S(:: crate :: x :: y);

(observe o prefixo :: para indicar o 'namespace' raiz)

Isso é consistente com a forma como outros namespaces raiz precisam ser referenciados em submódulos (por exemplo, ::std::x::y ).

Apenas eliminar a ambigüidade de crate -como-a-visibilidade seria um tanto surpreendente, eu acho. Mas pode ser uma boa ideia "canonizar" essa solução alternativa um pouco e garantir que crate:: seja sempre usado com :: esquerda (fora de use s, é claro). Como você apontou, isso aumenta a simetria com caminhos semelhantes a ::std::x::y e deixa a forma não prefixada para caminhos verdadeiramente relativos ( self:: / super:: / something_in_scope:: ).

Devemos fazer isso? Permitir crate::x::y em caminhos não use torna crate mágico, ao mesmo tempo que aplica ::crate::x::y ao mesmo nível das dependências, que é o que nós está tentando sugerir de qualquer maneira.

@rpjohnst

impor que crate:: seja sempre usado com um :: (fora dos usos, é claro)

Isso pode ser razoável, pelo menos para começar (nada impede que relaxe isso mais tarde).

Não sou fã da sintaxe use extern::bar::foo ou use crate::bar::foo . Parece muito barulhento. Prefiro um pouco de açúcar para isso. Eu sugiro extern bar::foo para isso.

Que tal adicionar mais uma regra implícita? Importar automaticamente extern crate para o namespace raiz, fazer uma expressão de caminho mais coincidente. (Não sou bom em inglês, por favor, aprenda minha visão com o exemplo a seguir)

por exemplo

  1. Nossa estrutura de projeto como esta:

src
| --lib.rs
| --foo.rs
| --foo
| ---- | --bar.rs

  1. você configura uma dependência em Cargo.toml, como
    [dependencies] serde = "3.0.0"

  2. adicionamos o mod bar ao mod foo e adicionamos o mod foo ao lib.rs,

  3. definimos uma função finlib em lib.rs, definimos uma função finfoo em foo.rs, definimos uma função finbar em bar.rs

Faça o escopo da caixa externa como o módulo de nível superior na caixa, então podemos escrever código como este em qualquer lugar.

para caminho completo / qualificado

::serde::Deserialize
::serde::x::y
::finlib                            // not ::crate::finlib
::foo::finfoo                   // not ::crate::foo::finfoo
::foo::bar::finbar           // not ::crate::foo::bar::finbar

caminho relativo, escreva assim

serde::Deserialize      // no need to write `use serde`
serde::x::y                   // no need to write `use serde`
finlib                          
foo::finfoo                  
bar::finbar       

primeiro procuramos serdefinlibfoo no escopo do mod atual, se não for encontrado lookup no mod supper, até o namespace raiz. se houver conflito de nomes, em vez disso escrevemos caminho completo.

também podemos usar self::bar::finbar em foo.rs para evitar que o nome seja procurado.

Não consigo encontrar o thread anterior que discutia isso, mas o compilador costumava funcionar dessa forma e causava grandes problemas para a resolução de nomes. IIRC @pcwalton ou @ arielb1 provavelmente sabem mais.

A solução mais fácil para essa ambigüidade não seria usar uma palavra-chave diferente para o modificador de visibilidade local da caixa (ou seja: a substituição pub(crate) ). Por exemplo, local , conforme sugerido muitas vezes antes em discussões RFC anteriores. Então struct S(local :: x :: y) é diferente de struct S(crate :: x :: y) .

Isso apenas introduz outra ambigüidade entre <visibility> <absolute path> e <relative path starting with the new keyword> , já que a nova palavra-chave teria que ser contextual.

@rpjohnst ah caramba .. Mas esse não é um problema que as épocas foram projetadas para resolver? Por exemplo: na época atual, usamos apenas pub(crate) e, na época seguinte, introduzimos uma nova palavra-chave não contextual que é mais 'ergonômica'.

@ neon64 sim, mas é uma afirmação da RFC de que não requer uma nova época. Essa afirmação parece não ser válida.

Funciona perfeitamente - atualmente não há código que use os caminhos crate visibility ou crate:: , portanto, apenas o novo código será afetado. Contanto que escolhamos uma resolução e a mantenhamos, não haverá problemas de compatibilidade.

Uma coisa que me ocorreu, com desculpas se isso foi mencionado antes em uma das discussões (não me lembro de ter visto isso no último casal):

Na última proposta, temos crate:: para nos referirmos a "nesta caixa" e self:: para nos referirmos a "neste módulo". Isso é um pouco inconsistente e potencialmente menos claro do que poderia ser: por um lado, onde self se refere a "isso", não é inerentemente óbvio "isso o que " e, inversamente, o fato de que existe um self:: que significa " este módulo", pode-se inferir que crate:: pode significar " alguma outra caixa", o que é uma confusão que de fato foi mencionada no tópico.

Uma solução possível seria eliminar self:: em favor de mod:: . Então teríamos crate:: significando "na caixa envolvente mais próxima", e mod:: significando "no módulo envolvente mais próximo", e seria claro e consistente. Nós também poderia resolver o problema onde não é possível fazer referência a itens dentro de um fn âmbito de forma qualificada a todos através da introdução de um fn:: prefixo, a sem surpresa média "na envolvente mais próxima fn ". (Não pensei se faria sentido ir mais longe e também ter coisas como trait:: ou impl:: .)

@glaebhoerl essa é uma proposta interessante. Pessoalmente, acho que tive a ideia de introduzir uma nova sintaxe para caminhos absolutos e descontinuar a existente. Não tenho certeza de como essa sintaxe deve ser, mas descreverei uma possibilidade abaixo (que eu sei que foi sugerida antes).

Imagine que temos a seguinte gramática para caminhos:

Path = AbsolutePath | RelativePath
AbsolutePath = 
    | `@` ID? 
    | `@` ID? `::` RelativePath
    | `self` :: RelativePath
    | `super` :: RelativePath
RelativePath = ID (`::` ID)*

Sob essa gramática, alguém faria referência a coisas de outras caixas começando com @crate , por exemplo:

use <strong i="13">@std</strong>::collections::HashMap;

Alguém faria referência à caixa local com apenas @ , por exemplo:

use @::something::in::my::crate;

(E use self::something permanece o mesmo de hoje, para melhor ou para pior.)

Algo bom sobre isso é que os caminhos absolutos são completamente distintos dos caminhos relativos, o que significa que agora temos a propriedade desejável de que se pode copiar e colar um caminho de use no código e funciona:

fn foo() {
    <strong i="24">@std</strong>::cmp::min(a, b) // OK
}

Isso não é verdade hoje, o que definitivamente me confunde de vez em quando.

Também eliminamos a ambigüidade da análise em torno de crate , portanto, você pode fazer pub Foo(crate @::MyType) ou o que quer que funcione bem.

(Em geral, ter caminhos relativos e absolutos começando com o mesmo :: tem sido uma fonte de dor muitas vezes, é a verdade.)

Uma coisa que não sei é se @foo é o melhor. A outra opção que acho que funciona e que pensei é [] :

  • [std]::collections e [crate]::collections // []::collections parecem muito estranhos.

Eu realmente não acho que devemos introduzir novos sigilos apenas para caminhos. Impor um :: em ::crate::foo é o suficiente para abordar o comentário de @glaebhoerl e eliminar a ambigüidade da análise. Ele também se ajusta ao modelo mental pretendido para crate:: mais de perto - é um substituto para o nome da caixa atual, não um prefixo de caminho como self:: .

(Em geral, ter caminhos relativos e absolutos começando com o mesmo :: tem sido uma fonte de dor muitas vezes, é a verdade.)

Não tenho certeza do que você quer dizer com isso. Não acho que nenhum caminho relativo comece com :: , certo?

@nikomatsakis @glaebhoerl independente de eu gostar ou não de suas sugestões (na verdade, posso aceitar as duas), podemos
Especialmente, estou um pouco confuso porque em # 44721 @nikomatsakis encerrou a discussão sobre o recurso com o argumento "vamos apenas falar sobre a implementação, por favor".

A notação @ e a notação [] foram ambas propostas (sendo eu um apoiador de ambas), mas eventualmente não conseguiram, pelo menos é minha impressão, devido às respostas negativas dos usuários .

Mesmo se não houver nenhum caso em que :: possa ser confundido com um caminho que começa em um identificador anterior e tem um :: interno, não é muito distinto visualmente.

Além disso, é menos sugestivo. @ é um mnemônico melhor. Com um :: você deve se perguntar se é como caminhos de nome de arquivo, onde / significa raiz (se você estiver em um sistema Unixy), ou se é uma abreviatura padrão, sem início coisa significaria "deixamos o nome de fora porque é relativo". Com um momento de reflexão, você pode ver que a primeira opção faz mais sentido, mas o ponto é que leva um momento para pensar. @ (ou algo assim) é instantaneamente distinguível tanto para o compilador quanto para o codificador, tornando mais fácil entender instantaneamente o que está acontecendo.

Como um @ mais fácil de distinguir do que um :: ? :: já é um mecanismo estabelecido tanto no Rust quanto no C ++!

@rpjohnst - Eu disse @ é distinto visualmente. Para expandir: ele salta sobre você. Não há perigo de confundir o posicionamento inicial vs. interno em seu modelo mental do fluxo de tokens.

@ é um token completamente novo sem nenhum significado e levaria muito mais do que "um momento para pensar" para descobrir. Para começar, confundir um :: com um :: interno não é um problema - não há razão para que alguém tenha de "pensar por um momento" para descartar a ideia de que um :: principal

@rpjohnst - Suas afirmações são verdadeiras, dado treinamento suficiente sobre o que :: significa (que é fornecido por experiência com C ++ ou Rust). Eu estava falando sobre aprendizagem e diferença intrínseca. "O mesmo símbolo usado em um contexto diferente" nunca será tão distinguível quanto "um símbolo único".

Eu poderia aceitar o argumento de que não vale a pena queimar @ como um símbolo exclusivo em um caso de uso como este, onde há uma alternativa tolerável.

@Ichoran : Acho que adicionar um novo token para uma determinada semântica ( @ ) à gramática Rust não é uma etapa a ser tomada de ânimo leve, e tenho uma leve suspeita de que estamos muito perto de fazer isso com @nikomatsakis e outras propostas. Por um lado, porque não podemos reutilizá-lo para outro propósito mais tarde na vida da linguagem (suponho que os caminhos sejam tão difundidos no código que o token @ poderia aparecer em muitos lugares). Também me pergunto qual é o efeito na percepção da complexidade do código Rust. Para um novato que não está acostumado a, por exemplo, C ++, eu acredito (mas não tenho pesquisas sobre isso) Rust é uma linguagem com uma notação bastante barroca e intimidante. Um dos objetivos estratégicos para este ano é otimizar a capacidade de aprendizagem e suponho que a acessibilidade do Rust. Então, talvez tenhamos que considerar isso ao imaginar @ porque a intuição é que ele se destacaria no código (o que @rpjohnst eu acho que questiona corretamente). Estou bastante claro o que quero dizer com isso?

(Sinta-se à vontade para corrigir ou esclarecer qualquer coisa que afirmei, já que simplesmente não tenho tempo para acompanhar de perto a discussão sobre a gramática de Ferrugem.)

@ est31

Independentemente de gostar das suas sugestões ou não (na verdade, posso aceitar as duas), podemos seguir o RFC?

Basicamente, eu concordo. Eu realmente não quero me envolver em grandes discussões agora - é o período implícito, afinal! - mas eu queria colocar a ideia @ "lá fora" para ferver em segundo plano. Em parte, porque tendo a ficar meio esquecido, e escrever coisas me ajuda a me lembrar delas mais tarde.

Minha sensação é que, neste ponto, a coisa certa a fazer é:

  • Implementando o RFC aproximadamente da forma como foi escrito.

    • Podemos querer, por exemplo, adotar a sugestão de @rpjohnst de ::crate para caminhos absolutos, apenas para resolver a desambigüidade da análise, porque parece um delta muito pequeno e, na verdade, aumenta a consistência geral.

  • Ganhe experiência em usá-lo.
  • Revisite o projeto, tendo em mente as alternativas que foram lançadas nesse ínterim e tome as decisões finais de estabilização.

Era com esse espírito que eu pretendia escrever meu comentário, embora eu não tenha deixado isso claro. Talvez fosse melhor mantê-lo em um arquivo privado. : woman_shrugging:

EDIT: Além disso, estou ciente de que @ e [] foram levantados anteriormente, embora eu não me lembre se a notação @::foo foi mencionada antes por ser relativa à atual engradado. Portanto, não pretendo reivindicar a autoria da ideia.

OTOH, a ideia que mencionei não foi levantada anteriormente e não é tanto uma modificação do RFC, mas uma extensão dele. Além disso, "A sintaxe final para caminhos absolutos; há mais bicicletas a serem feitas aqui em um contexto onde podemos realmente experimentar as várias opções." está listado explicitamente como uma questão não resolvida no corpo do problema. Concordo que, em geral, devemos tentar evitar novos litígios de RFCs aceitos, mas não acho que essa situação seja comparável à que tivemos com, por exemplo, faixas inclusivas (ugh).

Veja também este tópico de discussão:

https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678

Bem-vindo a mais um episódio da Grande Aventura dos Módulos! Quando nos encontramos pela última vez, nossos bravos aventureiros finalmente chegaram à lendária terra, tendo aceitado a RFC # 2126. Lá eles fizeram uma breve pausa e se prepararam para começar o período Impl. Nesse período, muito trabalho foi feito e, de fato, os contornos do sistema de módulos foram implementados. Mas eis que ainda havia algumas questões incômodas para resolver ... e isso nos leva a este tópico de discussão.

Em uma linguagem menos floreada: durante o período de implementação, fizemos muito progresso na implementação da RFC “Esclarecer e otimizar caminhos e visibilidade” (junto com uma série de RFCs relacionadas). Na verdade, progredimos quase demais - implementamos algumas variantes diferentes e gostaria de iniciar uma discussão sobre o que realmente queremos.

Gostaria de poder estabilizar este excelente trabalho algum dia =) e isso exigirá que escolhamos uma das variantes ... daí o tópico.

Pessoalmente, sou fã da sintaxe @ mencionada por @nikomatsakis. É conciso e razoavelmente autoexplicativo. Teremos que introduzir algum tipo de nova sintaxe aqui, então é melhor um caractere especial do que um nome reservado como crate (ugh).

Parece que agora podemos resolver o segundo indicador externo, especialmente porque https://github.com/rust-lang/cargo/issues/1311 agora está resolvido (na verdade, ele já deveria estar fechado). Eu poderia resolver isso com um pouco de orientação e uma decisão sobre a sintaxe @ vs. crate . Pensamentos?

Adicionados problemas de rastreamento para os dois lints não implementados.

Ocorreu-me que temos um pequeno problema de compatibilidade: se quisermos que extern crate se torne implícito, há uma alteração importante envolvida em fazer esse trabalho - extern crate força as caixas a serem conectadas; que pode causar erros se você especificar caixas extras em Cargo.toml, mas não lib.rs que não se ligam de forma clara (por exemplo, panic = desenrolar caixas com panic = abortar ou caixas que exportam o mesmo símbolo). Determinamos que esta é uma ruptura não problemática?

Ocorre-me que temos um pequeno problema de compatibilidade: se quisermos que a caixa externa fique implícita, há uma grande mudança envolvida em fazer esse trabalho - a caixa externa força as caixas a serem conectadas; que pode causar erros se você especificar caixas extras em Cargo.toml, mas não lib.rs que não se ligam de forma clara (por exemplo, panic = desenrolar caixas com panic = abortar ou caixas que exportam o mesmo símbolo). Determinamos que esta é uma ruptura não problemática?

A única solução que vi para isso até agora é apenas vincular implicitamente uma caixa ao importar algo dessa caixa; no entanto, isso ainda apresenta alguns problemas. Existem várias maneiras de as caixas exporem a funcionalidade de outras formas além da simples exportação de símbolos de ferrugem a serem importados, como vincular em uma determinada biblioteca nativa ou exportar símbolos #[no_mangle] para resolver algumas dependências em uma biblioteca nativa. Depois que extern crate for removido, a única maneira de forçar a ligação de tal caixa é fazê-la exportar um símbolo de ferrugem placebo para ser importado conforme necessário. Não sei quem achou que seria melhor forçar as pessoas a usar essa solução alternativa em vez de aderir a extern crate .

Sim, usamos explicitamente esse padrão no Firefox - há uma caixa de nível superior gkrust que contém apenas instruções extern crate para caixas que precisam ser vinculadas (expõem funções C externas escritas em Rust que o Firefox chama)

Você ainda pode fazê-lo funcionar exigindo que as pessoas use cratename; em lib.rs para forçar isso.

Que tal ter um atributo #![link_crates(stylo,webrender)] para essa finalidade? Ao contrário de extern crate , ele não adicionaria a caixa à árvore de nomes. Dar a ele um novo nome indicaria claramente aos leitores que você está incluindo as caixas apenas para ligação e que a declaração não deve ser removida, enquanto extern crate deve.

Isso resolve o problema oposto?

Ah, entendo, para as pessoas da época de 2015, isso permite que atualizem seu código sem mudar de época.

Mas isso significa que _todo mundo_ precisaria usar uma chave link_crates . Isso não é o ideal.

Que tal ter um atributo #! [Link_crates (stylo, webrender)] para essa finalidade? Ao contrário da caixa externa, ele não adicionaria a caixa à árvore de nomes.

E as caixas que podem ser usadas como caixas apenas com links, como caixas com símbolos de ferrugem ou ambos?

@whitequark se você usar símbolos dessas caixas, você obterá o link de graça como já é o caso agora. O atributo estaria no local de uso para que você, como usuário, decidisse como usar a caixa.

@Manishearth

Mas isso significa que todos precisariam usar uma chave link_crates. Isso não é o ideal.

Não. Eu não expressei minha proposta bem o suficiente. Eu quero manter a parte onde use cratename::item; tem o mesmo efeito que link_crates intacta. O recurso link_crates deve ser usado se você não precisar de nenhum item da caixa, mas precisar do enlace. Se você importar qualquer item da caixa, obterá uma ligação como a proposta da RFC.

Só não acho que ter use cratename; em seu código para esse propósito seja bom porque confundiria lints e (o mais importante) leitores / gravadores de código e, portanto, acho que deveria haver um recurso dedicado para aquele legítimo (mas raramente) caso de uso.

@ est31 Bikeshedding na sintaxe de link_crates , em vez de tê-lo como um atributo, por que não fazemos algo como extern crate foo; ?

@ retep998
Boa ideia! :sorriso:
https://github.com/rust-lang/rfcs/pull/2166 até introduziu extern crate foo as _; para evitar trazer o nome da caixa para o escopo / módulo para caixas apenas de ligação.

@ est31 Bikeshedding na sintaxe para link_crates, em vez de tê-lo como um atributo, por que não fazemos algo como extern crate foo ;?

A questão toda é se livrar da sintaxe extern crate a longo prazo.

@alexreg O objetivo é torná-lo desnecessário no caso comum. Isso não significa que ele precisa ser totalmente erradicado, talvez ainda seja uma boa solução para o caso de uma caixa que precisa ser conectada sem que nenhum item Rust seja usado. (E, de qualquer forma, ele viverá enquanto o compilador suportar épocas mais antigas.)

@SimonSapin Mas avançando, se for apenas um caso extremo, talvez não faça sentido ter uma sintaxe especial para isso, e um atributo (como proposto acima) faria mais sentido.

Eu ainda acho que use foo ou use foo as _ deve ser suficiente aqui, realmente

Concorde com @Manishearth.

Resumindo minha opinião sobre extern crate; :

Vantagens:

  • extern crate fornece uma lista abrangente de caixas usadas no topo da sua biblioteca. Agora, com caixas normais, este não é assim tão relevante como há Cargo.toml, mas se você tem exemplos isso é muito útil, pois dá-lhe uma lista de caixas para importação. Pense bem, e se seus exemplos apenas importassem um subconjunto de suas dependências de desenvolvimento? Isso traz grandes benefícios ao tentar descobrir a API de uma nova caixa, também conhecida como benefícios de capacidade de aprendizado. Por outro lado, você pode mencionar que extern crate pode aparecer em qualquer lugar da caixa, de modo que a lista não precisa ser exaustiva, mas para exemplos isso é menos relevante. Sempre podemos mudar a caixa externa para trabalhar apenas na raiz da caixa se quisermos.

Desvantagens:

  • extern crate é um pequeno incômodo, pois significa mais coisas para digitar ao adicionar uma caixa. Acho que essa é a razão pela qual muitas pessoas são contra extern crate mas para mim não é a razão de motivação.
  • Vejo extern crate como parte de uma negociação: desistimos de extern crate mas ganhamos a distinção entre importar da própria caixa e importar da caixa externa. Este é um recurso muito mais útil e supera as desvantagens de capacidade de aprendizado da IMO com exemplos de código / testes. Esta é a razão pela qual concordo com a remoção de extern crate .

extern crate fornece uma lista abrangente de caixas usadas no topo da sua biblioteca. Agora, com caixas normais, isso não é tão relevante, como Cargo.toml, mas se você tiver exemplos, isso é muito útil, pois fornece uma lista de caixas para importar.

Não vejo como isso é relevante para a discussão aqui; este é um ponto contra um RFC já mesclado.

@Manishearth estava mais respondendo a @ retep998 aqui, que meio que sugeriu manter a caixa externa. E não, um ponto não é ilegítimo ou irrelevante apenas porque é contra uma RFC já incorporada. É preciso refletir e conhecer as vantagens e desvantagens das decisões. Ainda podemos, por exemplo, remover a caixa externa de lib.rs mas mantê-la por hello_world.rs para os benefícios de ergonomia e aprendizagem (para os usuários da biblioteca, não seus autores).

É irrelevante porque o que está sendo discutido (no comentário de Peter ao qual você responde) são caixas somente com link; que são um caso de uso de nicho o suficiente para "listar todas as suas caixas externas no topo" é um benefício marginal. Especialmente se você tiver dependências que _não_ também são engradados somente de link (isso costumava não ser verdade para o Firefox, mas agora é).

Se o seu ponto é mais geral sobre ter a caixa externa implícita não se aplica a testes (e não especificamente sobre caixas apenas de link), esse é um ponto interessante, mas eu realmente não concordo com isso porque vai ser mais confuso quando é usado em apenas metade do código.

Então, se não me engano, o único ponto de implementação restante aqui é # 48719. Alguém está lidando com isso agora? Se não, posso tentar, suponho ...

Sim, estamos testando coisas em # 50260

Sábado, 28 de abril de 2018, 9h15 Alexander Regueiro [email protected]
escreveu:

Então, se não me engano, o único ponto de implementação restante aqui é

48719 https://github.com/rust-lang/rust/issues/48719 . É qualquer um

lidar com isso agora? Se não, posso tentar, suponho ...

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-385187379 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ABivSMyg6L4nQ1O7nMcvY4JCGjWKRiq3ks5ttJWhgaJpZM4PaPWi
.

48722 está pronto. @Manishearth, você poderia atualizar o OP, por favor :)

@ mark-im @Manishearth https://github.com/rust-lang/cargo/issues/1311 também está completo, então talvez valha a pena transformar esse ponto em uma caixa de seleção e marcá-la. Mas estou curioso: qual é a abordagem quando o Cargo não é usado, indo para a frente? (Não que alguém sensato evite Cargo ...)

@alexreg O mecanismo que Cargo usa para dizer a rustc para renomear uma caixa é igualmente acessível para pessoas que não usam carga: --extern name_rustc_sees=path_to_dep.rlib .

Parece que terminaremos todo o estágio de implementação em breve - quando https://github.com/rust-lang/rust/pull/47992 chegar, na verdade. Estou perdendo alguma coisa? Fico feliz em ajudar a mover isso se houver alguma coisa a fazer.

Sim, está a caminho. Eu preciso encerrar isso, o que provavelmente farei mais cedo
semana que vem.

Em Qui, 3 de maio de 2018, 19:51 Alexander Regueiro [email protected]
escreveu:

Parece que terminaremos todo o estágio de implementação em breve - quando

47992 https://github.com/rust-lang/rust/pull/47992 terras, na verdade. Sou

Estou perdendo alguma coisa? Fico feliz em ajudar a mover isso se houver alguma coisa e
bobs restantes para fazer.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-386494018 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ABivSDYFonDWvxZEdxWXoykroaL2mJPxks5tu8I_gaJpZM4PaPWi
.

@Manishearth Good stuff.

@aturon com https://github.com/rust-lang/rust/pull/50260 pousado, está tudo implementado?

Alguém obteve o link para o plano que foi proposto após a RFC? Aquele que mais se assemelha ao que foi realmente implementado? (onde importações de --extern caixas são adicionadas ao prelúdio, e etc.)

Uma vez que esta é uma mudança tão significativa, talvez o RFC deva ser atualizado?

RFCs geralmente não são atualizados; eles não são uma especificação final. Eles são um
ferramenta de construção de consenso.

Na segunda-feira, 18 de junho de 2018 às 21:43, Quem? Eu?! notificaçõ[email protected] escreveu:

Uma vez que esta é uma mudança tão significativa, talvez o RFC deva ser atualizado?

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-398247665 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AABsij-Iwwb7vf4qBrsq9KFFqhuIbkVBks5t-Fc3gaJpZM4PaPWi
.

@ mark-im Essa postagem de discurso permanece dentro do espírito da RFC. Compare o resumo da RFC com aquele post, é basicamente o mesmo, além de pequenos detalhes. Houve RFCs em que a equipe decidiu fazer uma mudança totalmente diferente, mas esta não é uma delas.

Tudo isso é verdade, mas seria bom que tudo estivesse em um só lugar. Eu entendo o desafio logístico disso ...

🔔 🔔 Observe que uma prévia da edição 2018 agora está pronta e inclui as alterações do sistema de módulo. Por favor, dê uma olhada e deixe comentários aqui!

@aturon A última atualização, e a última reunião do grupo de trabalho do módulo, resultou em https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/205 , que disse especificamente " reduzida a uma única proposta central, com duas variantes ". Até onde sei, isso ainda era verdade. Tive a impressão de que nightly tinha implementado ambos, por meio de sinalizadores de recursos, para apoiar a experimentação com ambos.

Parece que a edição escolheu uma das duas variantes, escolheu aquela para suportar sem sinalizadores de recurso e documentou no guia de edição. Onde isso foi discutido? Até onde eu sei, nem o grupo de trabalho do módulo nem a equipe de lang estiveram envolvidos lá.

Consulte https://internals.rust-lang.org/t/relative-paths-in-rust-2018/7883 para uma nova proposta, construída a partir da visualização de 2018. Em particular, esta proposta fornece mais consistência e uniformidade entre o módulo raiz e os submódulos, e usa a mesma resolução de nome tanto em use instruções quanto em usos diretos de caminhos no código.

Olá, apenas meus 2 centavos no ::some::path vs crate::some::path - eu prefiro o último, principalmente porque é mais fácil de ler como um inglês simples e não deixa uma pontuação maluca pendurada para o lado esquerdo.

Por favor, dê uma olhada e deixe comentários aqui!

Espero que seja isso que você quis dizer. Depois de revisar uma grande mudança na caixa de futuros, em que todos os pub(crate) s foram alterados para crate , estou mais convencido de que usar crate tanto nas importações quanto como uma visibilidade modificador parece não natural e confuso.

crate enum Either<T, U> {
    A(T),
    B(U),
}

Acho especialmente confuso quando os dois são usados ​​juntos:

crate use crate::foo;

Como mencionei no problema do pub(crate) em apenas crate .

(Observação: não estou comentando sobre nenhuma outra parte das mudanças, que parecem boas para a consistência, apenas a mudança de pub(crate) para crate simples.)

@seanmonstar Com as alterações adicionais propostas para o sistema de módulos na visualização da próxima edição, espero que crate::foo se torne mais raro e crate use crate:: pareça uma ocorrência especialmente rara.

Com o sistema de módulo na visualização inicial de 2018, você precisaria escrever crate:: mesmo para referências mais profundas em sua caixa. Com o sistema de módulos propostos, você só precisa crate:: referências em sua caixa (por exemplo, do foo.rs para lib.rs, ou de foo / bar.rs para foo.rs), mas não para referências para baixo em sua caixa (por exemplo, do lib.rs para foo.rs, ou de foo.rs para foo / bar.rs). E geralmente, eu esperaria reexportar (seja via pub use ou crate use ) para reexportar algo de um módulo mais profundo em um módulo de nível superior, não o contrário.

Portanto, em geral, ficaria surpreso em ver crate use crate::foo; .

E, no entanto, em um projeto no qual estou trabalhando, tenho exatamente esse cenário. Eu tenho um módulo que contém vários auxiliares "genéricos" e, em seguida, outro módulo que define uma característica básica + combinadores, e uma vez que eles fazem uso de alguns auxiliares genéricos, eu reexportei para me ajudar em outras partes do engradado:

Atualmente:

// in filter/mod.rs
pub(crate) use ::generic::{Combine, Func};

// in filters/foo.rs
use ::filter::{Filter, Func};

O lint vai querer que eu mude isso para:

// in filter/mod.rs
crate use crate::generic::{Combine, Func};

Então, eu não estava tentando pensar em uma hipótese que ninguém jamais encontrará. É real.

Eu concordo totalmente com @seanmonstar. Não vamos sobrecarregar essa palavra-chave, a menos que seja necessário (o que não é necessário).

Sim, você está certo de que as reexportações _usualmente_ borbulham, mas ser reexportado _lateralmente_ também é uma coisa, como Sean descreve. É algo que estou pensando em fazer também para a caixa de mídia de servo, uma vez que os arquivos estão bem divididos, mas isso significa apenas muitas importações comuns em todas as nossas implementações de nó.

Será possível continuar declarando o que é usado em um módulo e possivelmente exigir uso explícito, talvez como um atributo crate? Eu prefiro ser capaz de saber, olhando para um arquivo de origem, o que está em escopo dentro dele. Ter algumas linhas de importações de nível raiz no início de um arquivo de origem ajuda a dar algum contexto para o que realmente está acontecendo dentro dele, em vez de apenas ter todas as dependências externas implicitamente no escopo e ajuda muito na refatoração.

Tendo tentado a conversão em uma das minhas caixas, gostaria de mencionar como alguns outros que vi falando sobre isso, não estou convencido de usar crate como um modificador de visibilidade em vez de pub(crate) é uma melhoria. Meu raciocínio aqui é que o apelido de engradado é amplamente usado e apenas colocá-lo na frente dos itens torna-o um pouco confuso (me lembra da sopa de palavras-chave que você obtém em algumas linguagens, como public static void main() do Java - pelo menos Rust tem o tipo de retorno no final). pub(crate) pelo menos retém pub para tornar mais óbvio que crate trata da visibilidade neste contexto.

Aqui está outra instância que acabei de encontrar que combina a palavra-chave crate em um modificador de visibilidade e um caminho, que parece ainda mais provável do que a instância crate use crate... .

Atual:

pub(crate) struct Bar {
    pub(crate) foo: ::Foo,
}

pub(crate) struct Baz(pub(crate) ::Foo);

Com alterações deste problema de rastreamento:

crate struct Bar {
    crate foo: crate::Foo,
}

crate struct Baz(crate crate::Foo);

Eu pessoalmente acho o novo mais confuso do que o jeito atual.

Quando li pela primeira vez o RFC para converter pub(crate) em crate , pensei que parecia um acéfalo. pub(crate) parece muito estranho em comparação com o resto da sintaxe Rust relacionada nesta área.

Mas...

Depois de converter um pequeno jogo do Piston para Rust 2018 e vê-lo em primeira mão, devo admitir que simpatizo com o comentário de crate puro espalhado em todos os lugares foi cognitivamente chocante. Não tenho certeza se iria me acostumar naturalmente com isso com o tempo ou não.

Como outros já disseram, parece que a palavra-chave significa algo muito diferente em ambos os contextos.

use crate::menu::{Sound, Volume};

crate mod color;

...

/// A type for storing text and an associated color it should
/// be drawn as.
crate struct ColoredText {
    crate color: types::Color,
    crate text: &'static str,
}

Quero deixar claro que realmente gosto do resto desta proposta (as atualizações do sistema do módulo).

Sinto que pub(crate) parece um pouco pesado e estranho, mas também crate parece um pouco fora do lugar.

Poderíamos apenas considerar uma palavra-chave diferente aqui em vez de reutilizar crate ?

@ neon64 Sugerido internal que parece razoável, mas pode haver outros. Como podemos adicionar palavras-chave em Rust 2018, temos a oportunidade agora de considerar isso.

internal parece mais pesado do que pub(crate) para mim. Não é mais curto e é uma nova palavra-chave.

Que tal int ? : P

Dentro ( ins ), interno ( int ), protegido ( pro ), local ( loc ), secreto ( sec ), interior ( inn ) existem muitas alternativas para a palavra-chave crate .

Entretanto, int confundirá os desenvolvedores de C / C ++? (Palavra-chave inteira)

como um programador, quando você vê um pub, você o trata como público, se você deseja introduzir outro nível de visibilidade, então você precisa que seja um adjetivo para permanecer consistente. Tanto quanto me lembro, pub significava publicar inicialmente e, em ambos os casos, pub (caixa) parece mais natural. Caixa é uma palavra-chave estranha para isso.
Acho que é melhor deixar o pub (caixa) como está ou adicionar abreviatura de adjetivo.

também acho que a dificuldade de nomear vem do fato de pub ser abreviatura, se fosse público acho que não seria um problema chamá-lo de privado ou interno e esquecer.

Pessoalmente, não vejo problema com pub(crate) . A sintaxe é clara e inequívoca à primeira vista e consistente com o Rust real. Não acho que você precise digitar isso com freqüência suficiente para que 5 toques de tecla extras sejam um problema.

@UtherII

A razão pela qual precisamos de um nome curto para pub(crate) é porque muitos (talvez até a maioria ) dos usos atuais de pub serão substituídos por ele.

No Rust 2018, usar pub para itens efetivamente privados (porque eles aparecem em módulos privados) será um aviso. Em vez disso, deve-se usar pub(crate) para esses itens. Esta convenção melhorará a legibilidade do código: um item é visível para outras caixas se e somente se estiver marcado pub , enquanto atualmente se está visível para outras caixas pode não ser óbvio à primeira vista.

Desculpe, eu acidentalmente criei um novo problema para isso em vez de responder a esta discussão. Ops, sou novo no github e simplesmente cliquei em um botão que me fez entrar no que achei que estava respondendo aqui, mas que na verdade estava criando um novo problema. Vou colar o que escrevi no novo problema aqui, e meu novo problema pode ser excluído, desculpe por isso.

Visto que o manual de edição sugeria que as pessoas deixassem comentários aqui, decidi fazê-lo.

Eu realmente não me importo com crate :: ou :: para acessar elementos da raiz da caixa. :: é o que já é a sintaxe, entretanto, se for possível ter crate :: e :: eu acho que ambos devem ser usados. A meu ver, é que o novo sistema de caixas sugerido em relação aos caminhos é essencialmente equivalente à sintaxe antiga, com a única diferença de que você não precisa mais usar a palavra-chave extern e as coisas são mais acessíveis do que a necessidade de usá-las explicitamente em submódulos, eles são importados implicitamente em todos os lugares.

A única outra adição parece ser que você inicia a raiz da caixa com crate :: em vez de ::. Eu prefiro começar com apenas ::, já que isso é consistente com a maneira que eu o aprendi originalmente, no entanto, posso ver pessoas que não aprenderam o sistema de módulos ainda achando iniciá-lo com crate :: mais intuitivo. Por que não permitir as duas formas de sintaxe? Existe algum motivo que torna inviável ter os dois? Se ambos podem ser apoiados, eu endosso totalmente o apoio a ambos. Se apenas um puder ser suportado, estou mais inclinado a :: assim como é o que estou acostumado, embora possa ser mais fácil para iniciantes aprender como engradado :: e eu posso atualizar trivialmente meu entendimento sobre ele para ser assim, então talvez minha motivação seja egoísta.

Então, essencialmente, eu realmente não me importo, mas pessoalmente prefiro ::, mas acho que apoiar os dois seria o ideal, embora se um deve ser selecionado e as pessoas pensam que começar com engradado :: é superior para novatos, então eu não não se oponha a isso.

Como #[path] deve funcionar com módulos aninhados no Rust 2018? (https://github.com/rust-lang/rust/issues/35016#issuecomment-409185342)

IIUC, agora, dados dois arquivos src/lib.rs e src/bar.rs , não há X que possa ser substituído em:

mod foo {
    #[path = "X/bar.rs"]
    mod bar;
}

de forma que o módulo bar.rs será encontrado, porque o caminho para bar.rs sempre será src/foo/X/bar.rs que é inválido porque o diretório foo não existe.

Como estamos buscando um bom nome para uma substituição de pub(crate) e a equipe principal ainda está procurando feedback, gostaria de compartilhar minha experiência e oferecer uma sugestão.

Em uma caixa que escrevi, achei irritante digitar pub(crate) todos os lugares. Então, eu apenas abreviei para pub e, inadvertidamente, exportei muitos símbolos que não precisavam estar visíveis fora da caixa. Opa. 😛 (No meu caso específico, não é realmente um problema, porque a caixa é interna e não publicada, mas ainda assim! Conveniência sobre a correção.) Então, sim, acredito fortemente que precisamos de algo melhor do que um mashup de duas palavras-chave para transmitir visibilidade no nível da caixa .

Mas não acredito que crate seja a palavra-chave certa para isso (veja acima o feedback de outras pessoas sobre este tópico), e sinto que algumas outras palavras-chave sugeridas não entenderam ao abordar o problema a partir da perspectiva da raiz da caixa; o problema está na perspectiva do módulo, ou seja, na linha de código específica que contém a palavra-chave. Em outras palavras, o código não está tentando fornecer "localidade da caixa", ele está tentando exportar a referência do módulo onde ela está definida.

Nesse sentido, gosto da palavra-chave export (mesmo que seja possível confundir com extern , mas talvez isso seja discutível, já que extern crate está morto?) export struct Foo; parece muito legível e alinha-se com alguns outros idiomas (ish). Não consegui encontrar nenhuma menção de export como palavra-chave, neste RFC ou em outro lugar. Então, também há isso.

Para completar, ele cobre os casos de uso levantados por @seanmonstar , @johnthagen , et al .:

export use crate::generic::{Combine, Func};

// Or even better using relative paths
export use ::generic::{Combine, Func};
export struct Bar {
    export foo: crate::Foo,
}

export struct Baz(export crate::Foo);
use crate::menu::{Sound, Volume};

export mod color;

// ...

/// A type for storing text and an associated color it should
/// be drawn as.
export struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}

Dito isso, sou a favor de matar pub(crate) com fogo. Eu até prefiro crate , FWIW.

@parasyte O problema que vejo com export é que pode ser confundido com "esta caixa exporta ____" (que é para isso que serve pub ), mas vejo como você está defendendo um perspectiva diferente.

Parece que a maioria das pessoas concorda que pub(crate) não é ideal, e muitos levantaram questões de que a palavra-chave substantiva crate , que agora é usada em outros contextos, pode ser chocante como uma substituição. Certificar-se de que consideramos totalmente outras palavras-chave (potencialmente novas) parece ser um bom uso de tempo antes que o Rust 2018 defina isso como pedra.

Eu não ouvi nenhum feedback "oficial" se ainda estiver aberto para discussão?

No interesse de introduzir mais algumas palavras ao longo das linhas da sugestão de @johnthagen que export parece mais com pub que pub(crate) ):

shared use ::generic::{Combine, Func};
shared struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}
global use ::generic::{Combine, Func};
global struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}

Também poderíamos seguir os passos do Java e usar algo como protected , mas não tenho certeza se isso é particularmente fácil de intuir. Também há local (no sentido de crate-local), mas acho que global tem menos probabilidade de confundir (por exemplo, local poderia ser _file_-local).

Como as pessoas se sentiriam sobre pub(cr) ou mesmo apenas cr ?

Usar crate parece bom demais para deixar de lado. Já é uma palavra-chave, seu uso anterior em extern crate está indo embora. Seu outro uso já está relacionado à visibilidade pub(crate) .

Se você apertar os olhos um pouco usando engradado como adjetivo, não soa tão desconcertante. Palavras como 'casa' podem ser usadas como adjetivos muito bem. IANAEnglishProfessor.

Acho que reexportar um item visível da caixa não é super problemático. Pessoalmente, eu apenas reexportei um item em um pai direto do módulo que o define, o que significa que você (provavelmente) deseja usar self vez de crate (apesar do caso de organização de código de seanmonstar ) Por exemplo.

    mod detail {
        crate struct Foo;
    }

    crate use self::detail::Foo;

Usar a caixa como uma visibilidade combinada com o caminho absoluto para um tipo (novamente usando o exemplo de seanmonstar) parece mais problemático: crate struct Foo(crate crate::Bar); em oposição a pub(crate) struct Foo(pub(crate) ::Foo); . Minha única esperança é que essa construção não seja popular e, portanto, a transição não criará essa sopa de caixote. Os usuários podem evitar isso importando explicitamente:

use crate::Bar;

crate struct Foo(crate Bar);

Eu gosto da sugestão de share ou algo parecido. give , provide , deliver , offer , serve , post , forward .. . Se ele deve ser um adjetivo, todos estes podem ser transformadas com um sufixo: shared , givable , providable , etc.

Para pegar no JavaScript por um momento, o ES6 nem mesmo tem um conceito de pacote versus módulo embutido na linguagem. Existem apenas módulos. A palavra-chave export no ES6 sempre exporta a referência do módulo; fica então a cargo de outro módulo import que referencie por caminho se quiser usá-lo.

Isso não é muito diferente de pub e use , respectivamente. e eu acho que é daí que parte da confusão viria com o uso de uma palavra-chave export . pub(crate) é na verdade uma espécie de nicho. É por isso que optei por usar apenas pub no passado. ; (

O problema do modificador de visibilidade crate foi extraído para # 53120. Mais debates e decisões devem continuar por lá.

O problema das alterações de mod.rs foi extraído para # 53125. Mais debates e decisões devem continuar por lá.

O problema da descontinuação de extern crate , bem como de use crate_name::foo e crate_name::foo Just Work ™, foi extraído para https://github.com/rust-lang/rust/ questões / 53128. Mais debates e decisões devem continuar por lá.

A questão de escolher um sistema de caminho de módulo foi extraída para https://github.com/rust-lang/rust/issues/53130.

Tendo extraído todos os bits deste problema em problemas separados; Estou fechando este.

@Centril : https://doc.rust-lang.org/unstable-book/print.html#extern_prelude links aqui. Onde isso está sendo discutido? Se essa informação estiver realmente faltando, você poderia adicioná-la ao OP?

@ sanmai-NL você pode refrescar minha memória sobre o que foi o "prelúdio externo"?

Se for apenas a capacidade de fazer use some_crate::foo::bar; , isso deve ser https://github.com/rust-lang/rust/issues/53128.

Parte disso está sendo discutido em https://github.com/rust-lang/rust/issues/54230.

@ sanmai-NL Acredito que o problema seja principalmente para diagnósticos.

extern_prelude está crate_name::foo::bar fora dos caminhos de use (importar).

@Centril

você pode refrescar minha memória sobre o que foi o "prelúdio externo"?

Em geral, "prelúdio" é usado atualmente para todos os nomes que estão no escopo de toda a caixa e não estão anexados a um módulo específico. (Existem muitos deles, na verdade.)

@petrochenkov Então, qual é o prelúdio "externo" em relação a isso?

@alexreg
As caixas passadas com --extern estão no escopo de toda a caixa, embora não sejam anexadas a nenhum módulo específico.

Seria ótimo se essas informações, por mais voláteis que fossem, fossem registradas em alguma fonte oficial de documentação. Esp. se houver menções externas do conceito, por exemplo, no livro Instável. Não estou dizendo que os mantenedores que implementam esses conceitos deveriam fazer isso.

@petrochenkov Obrigado, faz sentido.

Tendo extraído todos os bits deste problema em problemas separados; Estou fechando este.

@Centril Rastreando problemas no link da versão beta atual aqui. Você atualizaria o comentário original com as informações mais recentes, para que as pessoas não precisem ler os comentários?

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