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

Comments

Projects
None yet
8 participants
@nixpulvis
Copy link

nixpulvis commented Dec 9, 2015

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

This comment has been minimized.

Copy link
Contributor

durka commented Dec 9, 2015

This would be nice.

@rphmeier

This comment has been minimized.

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

This comment has been minimized.

Copy link
Author

nixpulvis commented Dec 9, 2015

@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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Dec 9, 2015

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

petrochenkov commented Dec 9, 2015

@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

This comment has been minimized.

Copy link
Author

nixpulvis commented Dec 12, 2015

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

@nrc nrc added the T-lang label Aug 19, 2016

@themihai

This comment has been minimized.

Copy link

themihai commented Aug 25, 2016

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

This comment has been minimized.

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
You can’t perform that action at this time.