Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Paths in Use Statements #1400

Closed
nixpulvis opened this issue Dec 9, 2015 · 10 comments
Closed

Nested Paths in Use Statements #1400

nixpulvis opened this issue Dec 9, 2015 · 10 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@nixpulvis
Copy link

Use statements are a bit unwieldy from time to time. I find myself wanting to follow some kind of rule for how to do my use statements. One problem is with useing many things from a single crate. For example:

use bincode::SizeLimit;
use bincode::rustc_serialize::{DecodingError, encode, decode};

I think it would be nice to be able to collapse this into a single use statement as follows:

use bincode::{
    SizeLimit,
    rustc_serialize::{
        DecodingError,
        encode,
        decode
    }
};

I know that not everyone will like this example, but the ability to have paths inside of the {, } form of the use statement would be a nice addition in many cases. This feature seemed so intuitive to me I honestly almost expected it to already work like this.

@durka
Copy link
Contributor

durka commented Dec 9, 2015

This would be nice.

@rphmeier
Copy link

rphmeier commented Dec 9, 2015

I personally find it harder to scan, but that may be because I'm accustomed to separate use statements.
Overall, I think this would be a useful feature.

The one major complaint I have is that it requires more vertical scanning to determine what crate/module a type initially originates from.

@nixpulvis
Copy link
Author

@rphmeier I imagine that in practice this will actually make it easier to scan for what crate/module something is from. This is because one need only to search by indentation for the use statements inside each crate/module.

@oli-obk
Copy link
Contributor

oli-obk commented Dec 9, 2015

I've wanted this many times. This should also come with a style-guide requiring the indentation.

@petrochenkov
Copy link
Contributor

It's a pretty logical extension to #1219 and it predecessors, I think it came up before. Something like

use_item = [::]tree_import;
tree_import = prefix::{(suffix,)*}
suffix = relative-path [as name] | relative-path::* | tree_import

maybe with some restrictions on self and super.
Name resolution happens as if the import tree is flattened before resolving names.

One thing that can be perceived as a drawback is that this extension changes the look of imports quite heavily. For example, look at some file with lots of imports, like https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs
After reformatting it looks like:

Spoiler

pub use self::PathParsingMode::*;

use {
    abi,
    ast::{self, BareFnTy},
    ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier},
    ast::{Public, Unsafety},
    ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue},
    ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, Block},
    ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause},
    ast::{Constness, ConstTraitItem, Crate, CrateConfig},
    ast::{Decl, DeclItem, DeclLocal, DefaultBlock, DefaultReturn},
    ast::{UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf},
    ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain},
    ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox},
    ast::{ExprBreak, ExprCall, ExprCast, ExprInPlace},
    ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex},
    ast::{ExprLit, ExprLoop, ExprMac, ExprRange},
    ast::{ExprMethodCall, ExprParen, ExprPath},
    ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary},
    ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl},
    ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy},
    ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic},
    ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst},
    ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl},
    ast::{ItemExternCrate, ItemUse},
    ast::{LifetimeDef, Lit, Lit_},
    ast::{LitBool, LitChar, LitByte, LitByteStr},
    ast::{LitStr, LitInt, Local},
    ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces},
    ast::{MutImmutable, MutMutable, Mac_},
    ast::{MutTy, BiMul, Mutability},
    ast::{NamedField, UnNeg, NoReturn, UnNot},
    ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange},
    ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild},
    ast::{PolyTraitRef, QSelf},
    ast::{Return, BiShl, BiShr, Stmt, StmtDecl},
    ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField},
    ast::{BiSub, StrStyle},
    ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue},
    ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef},
    ast::{Ty, Ty_, TypeBinding, TyMac},
    ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer},
    ast::{TyParam, TyParamBounds, TyParen, TyPath, TyPolyTraitRef, TyPtr},
    ast::{TyRptr, TyTup, TyU32, TyVec},
    ast::TypeTraitItem,
    ast::{UnnamedField, UnsafeBlock},
    ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple},
    ast::{Visibility, WhereClause},
    attr::{ThinAttributes, ThinAttributesExt, AttributesExt},
    ast_util::{self, ident_to_path},
    codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap},
    diagnostic::{self, FatalError},
    ext::tt::macro_parser,
    parse::{
        self, classify,
        common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed},
        lexer::{Reader, TokenAndSpan},
        obsolete::{ParserObsoleteMethods, ObsoleteSyntax},
        token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString},
        token::{keywords, special_idents, SpecialMacroVar},
        new_sub_parser_from_file, ParseSess, PResult
    },
    util::parser::{AssocOp, Fixity},
    print::pprust,
    ptr::P,
    std::{
        collections::HashSet,
        io::prelude::*,
        mem,
        path::{Path, PathBuf},
        rc::Rc,
        slice
    }
};

Personally, I like it better, but it's a big stylistic change.

@oli-obk
Copy link
Contributor

oli-obk commented Dec 9, 2015

actually as I understand it it would still be one use statement per top level import:

pub use self::PathParsingMode::*;

use abi;
use ast::{
    self, BareFnTy,
    RegionTyParamBound, TraitTyParamBound, TraitBoundModifier,
    Public, Unsafety,
    Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue,
    BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, Block,
    BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause,
    Constness, ConstTraitItem, Crate, CrateConfig,
    Decl, DeclItem, DeclLocal, DefaultBlock, DefaultReturn,
    UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf,
    Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain,
    ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox,
    ExprBreak, ExprCall, ExprCast, ExprInPlace,
    ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex,
    ExprLit, ExprLoop, ExprMac, ExprRange,
    ExprMethodCall, ExprParen, ExprPath,
    ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary,
    ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl,
    ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy,
    Ident, Inherited, ImplItem, Item, Item_, ItemStatic,
    ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst,
    ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl,
    ItemExternCrate, ItemUse,
    LifetimeDef, Lit, Lit_,
    LitBool, LitChar, LitByte, LitByteStr,
    LitStr, LitInt, Local,
    MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces,
    MutImmutable, MutMutable, Mac_,
    MutTy, BiMul, Mutability,
    NamedField, UnNeg, NoReturn, UnNot,
    Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange,
    PatRegion, PatStruct, PatTup, PatVec, PatWild,
    PolyTraitRef, QSelf,
    Return, BiShl, BiShr, Stmt, StmtDecl,
    StmtExpr, StmtSemi, StmtMac, VariantData, StructField,
    BiSub, StrStyle,
    SelfExplicit, SelfRegion, SelfStatic, SelfValue,
    Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef,
    Ty, Ty_, TypeBinding, TyMac,
    TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer,
    TyParam, TyParamBounds, TyParen, TyPath, TyPolyTraitRef, TyPtr,
    TyRptr, TyTup, TyU32, TyVec,
    TypeTraitItem,
    UnnamedField, UnsafeBlock,
    ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple,
    Visibility, WhereClause,
    ThinAttributes, ThinAttributesExt, AttributesExt,
};
use ast_util::{self, ident_to_path};
use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
use diagnostic::{self, FatalError};
use ext::tt::macro_parser;
use parse::{
        self, classify,
        common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed},
        lexer::{Reader, TokenAndSpan},
        obsolete::{ParserObsoleteMethods, ObsoleteSyntax},
        token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString},
        token::{keywords, special_idents, SpecialMacroVar},
        new_sub_parser_from_file, ParseSess, PResult,
};
use util::parser::{AssocOp, Fixity};
use print::pprust;
use ptr::P;
use std::{
    collections::HashSet,
    io::prelude::*,
    mem,
    path::{Path, PathBuf},
    rc::Rc,
    slice,
};

@petrochenkov
Copy link
Contributor

@oli-obk
Empty prefixes are already permitted, so they can be put into use if nested paths are allowed, so this is a purely stylistic choice.

@nixpulvis
Copy link
Author

I would hope the convention would be something like one use per top level though in general.

@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label Aug 19, 2016
@themihai
Copy link

What about grouping the use statements as well?

use {
    abi;
    ast::{
        self, BareFnTy,
        RegionTyParamBound, TraitTyParamBound, TraitBoundModifier,
        Public, Unsafety,
        Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue,
        BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, Block,
        BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause,
        Constness, ConstTraitItem, Crate, CrateConfig,
        Decl, DeclItem, DeclLocal, DefaultBlock, DefaultReturn,
        UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf,
        Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain,
        ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox,
        ExprBreak, ExprCall, ExprCast, ExprInPlace,
        ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex,
        ExprLit, ExprLoop, ExprMac, ExprRange,
        ExprMethodCall, ExprParen, ExprPath,
        ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary,
        ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl,
        ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy,
        Ident, Inherited, ImplItem, Item, Item_, ItemStatic,
        ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst,
        ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl,
        ItemExternCrate, ItemUse,
        LifetimeDef, Lit, Lit_,
        LitBool, LitChar, LitByte, LitByteStr,
        LitStr, LitInt, Local,
        MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces,
        MutImmutable, MutMutable, Mac_,
        MutTy, BiMul, Mutability,
        NamedField, UnNeg, NoReturn, UnNot,
        Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange,
        PatRegion, PatStruct, PatTup, PatVec, PatWild,
        PolyTraitRef, QSelf,
        Return, BiShl, BiShr, Stmt, StmtDecl,
        StmtExpr, StmtSemi, StmtMac, VariantData, StructField,
        BiSub, StrStyle,
        SelfExplicit, SelfRegion, SelfStatic, SelfValue,
        Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef,
        Ty, Ty_, TypeBinding, TyMac,
        TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer,
        TyParam, TyParamBounds, TyParen, TyPath, TyPolyTraitRef, TyPtr,
        TyRptr, TyTup, TyU32, TyVec,
        TypeTraitItem,
        UnnamedField, UnsafeBlock,
        ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple,
        Visibility, WhereClause,
        ThinAttributes, ThinAttributesExt, AttributesExt,
    };
    ast_util::{self, ident_to_path};
    codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
    diagnostic::{self, FatalError};
    ext::tt::macro_parser;
    parse::{
        self, classify,
        common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed},
        lexer::{Reader, TokenAndSpan},
        obsolete::{ParserObsoleteMethods, ObsoleteSyntax},
        token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString},
        token::{keywords, special_idents, SpecialMacroVar},
        new_sub_parser_from_file, ParseSess, PResult,
    };
    util::parser::{AssocOp, Fixity};
    print::pprust;
    ptr::P;
    std::{
        collections::HashSet,
        io::prelude::*,
        mem,
        path::{Path, PathBuf},
        rc::Rc,
        slice,
    };
}

@crumblingstatue
Copy link

crumblingstatue commented Mar 24, 2017

If ergonomics really is a focus in 2016, then this would be a relatively simple, but useful ergonomic addition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

8 participants