diff options
| -rw-r--r-- | Cargo.lock | 12 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | README.md | 21 | ||||
| -rw-r--r-- | RELEASES.md | 2 | ||||
| -rw-r--r-- | compiler/rustc/Cargo.toml (renamed from src/rustc/Cargo.toml) | 8 | ||||
| -rw-r--r-- | compiler/rustc/src/main.rs (renamed from src/rustc/rustc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_apfloat/Cargo.toml (renamed from src/librustc_apfloat/Cargo.toml) | 4 | ||||
| -rw-r--r-- | compiler/rustc_apfloat/src/ieee.rs (renamed from src/librustc_apfloat/ieee.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_apfloat/src/lib.rs (renamed from src/librustc_apfloat/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_apfloat/src/ppc.rs (renamed from src/librustc_apfloat/ppc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_apfloat/tests/ieee.rs (renamed from src/librustc_apfloat/tests/ieee.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_apfloat/tests/ppc.rs (renamed from src/librustc_apfloat/tests/ppc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_arena/Cargo.toml (renamed from src/librustc_arena/Cargo.toml) | 6 | ||||
| -rw-r--r-- | compiler/rustc_arena/src/lib.rs (renamed from src/librustc_arena/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_arena/src/tests.rs (renamed from src/librustc_arena/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/Cargo.toml | 19 | ||||
| -rw-r--r-- | compiler/rustc_ast/README.md (renamed from src/librustc_ast/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs (renamed from src/librustc_ast/ast.rs) | 19 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/ast/tests.rs (renamed from src/librustc_ast/ast/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs (renamed from src/librustc_ast/attr/mod.rs) | 9 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/crate_disambiguator.rs (renamed from src/librustc_ast/crate_disambiguator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/entry.rs (renamed from src/librustc_ast/entry.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/expand/allocator.rs (renamed from src/librustc_ast/expand/allocator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/expand/mod.rs (renamed from src/librustc_ast/expand/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/lib.rs (renamed from src/librustc_ast/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs (renamed from src/librustc_ast/mut_visit.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/node_id.rs (renamed from src/librustc_ast/node_id.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/ptr.rs (renamed from src/librustc_ast/ptr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/token.rs (renamed from src/librustc_ast/token.rs) | 18 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs (renamed from src/librustc_ast/tokenstream.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/classify.rs (renamed from src/librustc_ast/util/classify.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/comments.rs (renamed from src/librustc_ast/util/comments.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/comments/tests.rs (renamed from src/librustc_ast/util/comments/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/lev_distance.rs (renamed from src/librustc_ast/util/lev_distance.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/lev_distance/tests.rs (renamed from src/librustc_ast/util/lev_distance/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/literal.rs (renamed from src/librustc_ast/util/literal.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/parser.rs (renamed from src/librustc_ast/util/parser.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/visit.rs (renamed from src/librustc_ast/visit.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/Cargo.toml | 22 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs (renamed from src/librustc_ast_lowering/expr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs (renamed from src/librustc_ast_lowering/item.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs (renamed from src/librustc_ast_lowering/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/pat.rs (renamed from src/librustc_ast_lowering/pat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/path.rs (renamed from src/librustc_ast_lowering/path.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/Cargo.toml | 18 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs (renamed from src/librustc_ast_passes/ast_validation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs (renamed from src/librustc_ast_passes/feature_gate.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/lib.rs (renamed from src/librustc_ast_passes/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/node_count.rs (renamed from src/librustc_ast_passes/node_count.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/show_span.rs (renamed from src/librustc_ast_passes/show_span.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/Cargo.toml | 14 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/helpers.rs (renamed from src/librustc_ast_pretty/helpers.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/lib.rs (renamed from src/librustc_ast_pretty/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pp.rs (renamed from src/librustc_ast_pretty/pp.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust.rs (renamed from src/librustc_ast_pretty/pprust.rs) | 11 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust/tests.rs (renamed from src/librustc_ast_pretty/pprust/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_attr/Cargo.toml | 21 | ||||
| -rw-r--r-- | compiler/rustc_attr/src/builtin.rs (renamed from src/librustc_attr/builtin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_attr/src/lib.rs (renamed from src/librustc_attr/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/Cargo.toml | 24 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/asm.rs (renamed from src/librustc_builtin_macros/asm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/assert.rs (renamed from src/librustc_builtin_macros/assert.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/cfg.rs (renamed from src/librustc_builtin_macros/cfg.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/cfg_accessible.rs (renamed from src/librustc_builtin_macros/cfg_accessible.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/cmdline_attrs.rs (renamed from src/librustc_builtin_macros/cmdline_attrs.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/compile_error.rs (renamed from src/librustc_builtin_macros/compile_error.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/concat.rs (renamed from src/librustc_builtin_macros/concat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/concat_idents.rs (renamed from src/librustc_builtin_macros/concat_idents.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/bounds.rs (renamed from src/librustc_builtin_macros/deriving/bounds.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/clone.rs (renamed from src/librustc_builtin_macros/deriving/clone.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs (renamed from src/librustc_builtin_macros/deriving/cmp/eq.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs (renamed from src/librustc_builtin_macros/deriving/cmp/ord.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs (renamed from src/librustc_builtin_macros/deriving/cmp/partial_eq.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs (renamed from src/librustc_builtin_macros/deriving/cmp/partial_ord.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/debug.rs (renamed from src/librustc_builtin_macros/deriving/debug.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/decodable.rs (renamed from src/librustc_builtin_macros/deriving/decodable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/default.rs (renamed from src/librustc_builtin_macros/deriving/default.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/encodable.rs (renamed from src/librustc_builtin_macros/deriving/encodable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/generic/mod.rs (renamed from src/librustc_builtin_macros/deriving/generic/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/generic/ty.rs (renamed from src/librustc_builtin_macros/deriving/generic/ty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/hash.rs (renamed from src/librustc_builtin_macros/deriving/hash.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/mod.rs (renamed from src/librustc_builtin_macros/deriving/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/env.rs (renamed from src/librustc_builtin_macros/env.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format.rs (renamed from src/librustc_builtin_macros/format.rs) | 49 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format_foreign.rs (renamed from src/librustc_builtin_macros/format_foreign.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs (renamed from src/librustc_builtin_macros/format_foreign/printf/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs (renamed from src/librustc_builtin_macros/format_foreign/shell/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/global_allocator.rs (renamed from src/librustc_builtin_macros/global_allocator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/global_asm.rs (renamed from src/librustc_builtin_macros/global_asm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/lib.rs (renamed from src/librustc_builtin_macros/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/llvm_asm.rs (renamed from src/librustc_builtin_macros/llvm_asm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/log_syntax.rs (renamed from src/librustc_builtin_macros/log_syntax.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/proc_macro_harness.rs (renamed from src/librustc_builtin_macros/proc_macro_harness.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/source_util.rs (renamed from src/librustc_builtin_macros/source_util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/standard_library_imports.rs (renamed from src/librustc_builtin_macros/standard_library_imports.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/test.rs (renamed from src/librustc_builtin_macros/test.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/test_harness.rs (renamed from src/librustc_builtin_macros/test_harness.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/trace_macros.rs (renamed from src/librustc_builtin_macros/trace_macros.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/util.rs (renamed from src/librustc_builtin_macros/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/Cargo.toml | 34 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/README.md (renamed from src/librustc_codegen_llvm/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/abi.rs (renamed from src/librustc_codegen_llvm/abi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/allocator.rs (renamed from src/librustc_codegen_llvm/allocator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/asm.rs (renamed from src/librustc_codegen_llvm/asm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/attributes.rs (renamed from src/librustc_codegen_llvm/attributes.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/archive.rs (renamed from src/librustc_codegen_llvm/back/archive.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/lto.rs (renamed from src/librustc_codegen_llvm/back/lto.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/profiling.rs (renamed from src/librustc_codegen_llvm/back/profiling.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/back/write.rs (renamed from src/librustc_codegen_llvm/back/write.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/base.rs (renamed from src/librustc_codegen_llvm/base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/builder.rs (renamed from src/librustc_codegen_llvm/builder.rs) | 19 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/callee.rs (renamed from src/librustc_codegen_llvm/callee.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/common.rs (renamed from src/librustc_codegen_llvm/common.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/consts.rs (renamed from src/librustc_codegen_llvm/consts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/context.rs (renamed from src/librustc_codegen_llvm/context.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs (renamed from src/librustc_codegen_llvm/coverageinfo/mapgen.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs (renamed from src/librustc_codegen_llvm/coverageinfo/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs (renamed from src/librustc_codegen_llvm/debuginfo/create_scope_map.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/doc.rs (renamed from src/librustc_codegen_llvm/debuginfo/doc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs (renamed from src/librustc_codegen_llvm/debuginfo/gdb.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs (renamed from src/librustc_codegen_llvm/debuginfo/metadata.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/mod.rs (renamed from src/librustc_codegen_llvm/debuginfo/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs (renamed from src/librustc_codegen_llvm/debuginfo/namespace.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/source_loc.rs (renamed from src/librustc_codegen_llvm/debuginfo/source_loc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/utils.rs (renamed from src/librustc_codegen_llvm/debuginfo/utils.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/declare.rs (renamed from src/librustc_codegen_llvm/declare.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs (renamed from src/librustc_codegen_llvm/intrinsic.rs) | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/lib.rs (renamed from src/librustc_codegen_llvm/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs (renamed from src/librustc_codegen_llvm/llvm/archive_ro.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs (renamed from src/librustc_codegen_llvm/llvm/diagnostic.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/ffi.rs (renamed from src/librustc_codegen_llvm/llvm/ffi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm/mod.rs (renamed from src/librustc_codegen_llvm/llvm/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm_util.rs (renamed from src/librustc_codegen_llvm/llvm_util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/metadata.rs (renamed from src/librustc_codegen_llvm/metadata.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/mono_item.rs (renamed from src/librustc_codegen_llvm/mono_item.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/type_.rs (renamed from src/librustc_codegen_llvm/type_.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/type_of.rs (renamed from src/librustc_codegen_llvm/type_of.rs) | 29 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/va_arg.rs (renamed from src/librustc_codegen_llvm/va_arg.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/value.rs (renamed from src/librustc_codegen_llvm/value.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/Cargo.toml | 36 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/README.md (renamed from src/librustc_codegen_ssa/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/archive.rs (renamed from src/librustc_codegen_ssa/back/archive.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/command.rs (renamed from src/librustc_codegen_ssa/back/command.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs (renamed from src/librustc_codegen_ssa/back/link.rs) | 121 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/linker.rs (renamed from src/librustc_codegen_ssa/back/linker.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/lto.rs (renamed from src/librustc_codegen_ssa/back/lto.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/mod.rs (renamed from src/librustc_codegen_ssa/back/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/rpath.rs (renamed from src/librustc_codegen_ssa/back/rpath.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/rpath/tests.rs (renamed from src/librustc_codegen_ssa/back/rpath/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/symbol_export.rs (renamed from src/librustc_codegen_ssa/back/symbol_export.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/write.rs (renamed from src/librustc_codegen_ssa/back/write.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/base.rs (renamed from src/librustc_codegen_ssa/base.rs) | 33 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/common.rs (renamed from src/librustc_codegen_ssa/common.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs (renamed from src/librustc_codegen_ssa/coverageinfo/ffi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/coverageinfo/map.rs (renamed from src/librustc_codegen_ssa/coverageinfo/map.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/coverageinfo/mod.rs (renamed from src/librustc_codegen_ssa/coverageinfo/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/debuginfo/mod.rs (renamed from src/librustc_codegen_ssa/debuginfo/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs (renamed from src/librustc_codegen_ssa/debuginfo/type_names.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/glue.rs (renamed from src/librustc_codegen_ssa/glue.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/lib.rs (renamed from src/librustc_codegen_ssa/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/meth.rs (renamed from src/librustc_codegen_ssa/meth.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/analyze.rs (renamed from src/librustc_codegen_ssa/mir/analyze.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs (renamed from src/librustc_codegen_ssa/mir/block.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/constant.rs (renamed from src/librustc_codegen_ssa/mir/constant.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs (renamed from src/librustc_codegen_ssa/mir/coverageinfo.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/debuginfo.rs (renamed from src/librustc_codegen_ssa/mir/debuginfo.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/mod.rs (renamed from src/librustc_codegen_ssa/mir/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/operand.rs (renamed from src/librustc_codegen_ssa/mir/operand.rs) | 50 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/place.rs (renamed from src/librustc_codegen_ssa/mir/place.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/rvalue.rs (renamed from src/librustc_codegen_ssa/mir/rvalue.rs) | 28 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/statement.rs (renamed from src/librustc_codegen_ssa/mir/statement.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mono_item.rs (renamed from src/librustc_codegen_ssa/mono_item.rs) | 8 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/abi.rs (renamed from src/librustc_codegen_ssa/traits/abi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/asm.rs (renamed from src/librustc_codegen_ssa/traits/asm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/backend.rs (renamed from src/librustc_codegen_ssa/traits/backend.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/builder.rs (renamed from src/librustc_codegen_ssa/traits/builder.rs) | 14 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/consts.rs (renamed from src/librustc_codegen_ssa/traits/consts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs (renamed from src/librustc_codegen_ssa/traits/coverageinfo.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/debuginfo.rs (renamed from src/librustc_codegen_ssa/traits/debuginfo.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/declare.rs (renamed from src/librustc_codegen_ssa/traits/declare.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/intrinsic.rs (renamed from src/librustc_codegen_ssa/traits/intrinsic.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/misc.rs (renamed from src/librustc_codegen_ssa/traits/misc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/mod.rs (renamed from src/librustc_codegen_ssa/traits/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/statics.rs (renamed from src/librustc_codegen_ssa/traits/statics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/type_.rs (renamed from src/librustc_codegen_ssa/traits/type_.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/write.rs (renamed from src/librustc_codegen_ssa/traits/write.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/Cargo.toml (renamed from src/librustc_data_structures/Cargo.toml) | 12 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/atomic_ref.rs (renamed from src/librustc_data_structures/atomic_ref.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/base_n.rs (renamed from src/librustc_data_structures/base_n.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/base_n/tests.rs (renamed from src/librustc_data_structures/base_n/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/binary_search_util/mod.rs (renamed from src/librustc_data_structures/binary_search_util/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/binary_search_util/tests.rs (renamed from src/librustc_data_structures/binary_search_util/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/box_region.rs (renamed from src/librustc_data_structures/box_region.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/captures.rs (renamed from src/librustc_data_structures/captures.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/const_cstr.rs (renamed from src/librustc_data_structures/const_cstr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/fingerprint.rs (renamed from src/librustc_data_structures/fingerprint.rs) | 30 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/flock.rs (renamed from src/librustc_data_structures/flock.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/frozen.rs (renamed from src/librustc_data_structures/frozen.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/fx.rs (renamed from src/librustc_data_structures/fx.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/dominators/mod.rs (renamed from src/librustc_data_structures/graph/dominators/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/dominators/tests.rs (renamed from src/librustc_data_structures/graph/dominators/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/implementation/mod.rs (renamed from src/librustc_data_structures/graph/implementation/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/implementation/tests.rs (renamed from src/librustc_data_structures/graph/implementation/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/iterate/mod.rs (renamed from src/librustc_data_structures/graph/iterate/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/iterate/tests.rs (renamed from src/librustc_data_structures/graph/iterate/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/mod.rs (renamed from src/librustc_data_structures/graph/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/reference.rs (renamed from src/librustc_data_structures/graph/reference.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/scc/mod.rs (renamed from src/librustc_data_structures/graph/scc/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/scc/tests.rs (renamed from src/librustc_data_structures/graph/scc/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/tests.rs (renamed from src/librustc_data_structures/graph/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/vec_graph/mod.rs (renamed from src/librustc_data_structures/graph/vec_graph/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/vec_graph/tests.rs (renamed from src/librustc_data_structures/graph/vec_graph/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/jobserver.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/lib.rs (renamed from src/librustc_data_structures/lib.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/macros.rs (renamed from src/librustc_data_structures/macros.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/map_in_place.rs (renamed from src/librustc_data_structures/map_in_place.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/obligation_forest/graphviz.rs (renamed from src/librustc_data_structures/obligation_forest/graphviz.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/obligation_forest/mod.rs (renamed from src/librustc_data_structures/obligation_forest/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/obligation_forest/tests.rs (renamed from src/librustc_data_structures/obligation_forest/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/owning_ref/LICENSE (renamed from src/librustc_data_structures/owning_ref/LICENSE) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/owning_ref/mod.rs (renamed from src/librustc_data_structures/owning_ref/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/owning_ref/tests.rs (renamed from src/librustc_data_structures/owning_ref/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/profiling.rs (renamed from src/librustc_data_structures/profiling.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/ptr_key.rs (renamed from src/librustc_data_structures/ptr_key.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sharded.rs (renamed from src/librustc_data_structures/sharded.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sip128.rs (renamed from src/librustc_data_structures/sip128.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sip128/tests.rs (renamed from src/librustc_data_structures/sip128/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/small_c_str.rs (renamed from src/librustc_data_structures/small_c_str.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/small_c_str/tests.rs (renamed from src/librustc_data_structures/small_c_str/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/snapshot_map/mod.rs (renamed from src/librustc_data_structures/snapshot_map/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/snapshot_map/tests.rs (renamed from src/librustc_data_structures/snapshot_map/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sorted_map.rs (renamed from src/librustc_data_structures/sorted_map.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sorted_map/index_map.rs (renamed from src/librustc_data_structures/sorted_map/index_map.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sorted_map/tests.rs (renamed from src/librustc_data_structures/sorted_map/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/stable_hasher.rs (renamed from src/librustc_data_structures/stable_hasher.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/stable_map.rs (renamed from src/librustc_data_structures/stable_map.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/stable_set.rs (renamed from src/librustc_data_structures/stable_set.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/stack.rs (renamed from src/librustc_data_structures/stack.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/svh.rs (renamed from src/librustc_data_structures/svh.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sync.rs (renamed from src/librustc_data_structures/sync.rs) | 4 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/tagged_ptr.rs (renamed from src/librustc_data_structures/tagged_ptr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/tagged_ptr/copy.rs (renamed from src/librustc_data_structures/tagged_ptr/copy.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/tagged_ptr/drop.rs (renamed from src/librustc_data_structures/tagged_ptr/drop.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/temp_dir.rs (renamed from src/librustc_data_structures/temp_dir.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/thin_vec.rs (renamed from src/librustc_data_structures/thin_vec.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/tiny_list.rs (renamed from src/librustc_data_structures/tiny_list.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/tiny_list/tests.rs (renamed from src/librustc_data_structures/tiny_list/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/transitive_relation.rs (renamed from src/librustc_data_structures/transitive_relation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/transitive_relation/tests.rs (renamed from src/librustc_data_structures/transitive_relation/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/unhash.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/vec_linked_list.rs (renamed from src/librustc_data_structures/vec_linked_list.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/work_queue.rs (renamed from src/librustc_data_structures/work_queue.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_driver/Cargo.toml | 40 | ||||
| -rw-r--r-- | compiler/rustc_driver/README.md (renamed from src/librustc_driver/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_driver/src/args.rs (renamed from src/librustc_driver/args.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_driver/src/lib.rs (renamed from src/librustc_driver/lib.rs) | 13 | ||||
| -rw-r--r-- | compiler/rustc_driver/src/pretty.rs (renamed from src/librustc_driver/pretty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/Cargo.toml (renamed from src/librustc_error_codes/Cargo.toml) | 4 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes.rs (renamed from src/librustc_error_codes/error_codes.rs) | 1 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0001.md (renamed from src/librustc_error_codes/error_codes/E0001.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0002.md (renamed from src/librustc_error_codes/error_codes/E0002.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0004.md (renamed from src/librustc_error_codes/error_codes/E0004.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0005.md (renamed from src/librustc_error_codes/error_codes/E0005.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0007.md (renamed from src/librustc_error_codes/error_codes/E0007.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0009.md (renamed from src/librustc_error_codes/error_codes/E0009.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0010.md (renamed from src/librustc_error_codes/error_codes/E0010.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0013.md (renamed from src/librustc_error_codes/error_codes/E0013.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0014.md (renamed from src/librustc_error_codes/error_codes/E0014.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0015.md (renamed from src/librustc_error_codes/error_codes/E0015.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0019.md (renamed from src/librustc_error_codes/error_codes/E0019.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0023.md (renamed from src/librustc_error_codes/error_codes/E0023.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0025.md (renamed from src/librustc_error_codes/error_codes/E0025.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0026.md (renamed from src/librustc_error_codes/error_codes/E0026.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0027.md (renamed from src/librustc_error_codes/error_codes/E0027.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0029.md (renamed from src/librustc_error_codes/error_codes/E0029.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0030.md (renamed from src/librustc_error_codes/error_codes/E0030.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0033.md (renamed from src/librustc_error_codes/error_codes/E0033.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0034.md (renamed from src/librustc_error_codes/error_codes/E0034.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0038.md (renamed from src/librustc_error_codes/error_codes/E0038.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0040.md (renamed from src/librustc_error_codes/error_codes/E0040.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0044.md (renamed from src/librustc_error_codes/error_codes/E0044.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0045.md (renamed from src/librustc_error_codes/error_codes/E0045.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0046.md (renamed from src/librustc_error_codes/error_codes/E0046.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0049.md (renamed from src/librustc_error_codes/error_codes/E0049.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0050.md (renamed from src/librustc_error_codes/error_codes/E0050.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0053.md (renamed from src/librustc_error_codes/error_codes/E0053.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0054.md (renamed from src/librustc_error_codes/error_codes/E0054.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0055.md (renamed from src/librustc_error_codes/error_codes/E0055.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0057.md (renamed from src/librustc_error_codes/error_codes/E0057.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0059.md (renamed from src/librustc_error_codes/error_codes/E0059.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0060.md (renamed from src/librustc_error_codes/error_codes/E0060.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0061.md (renamed from src/librustc_error_codes/error_codes/E0061.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0062.md (renamed from src/librustc_error_codes/error_codes/E0062.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0063.md (renamed from src/librustc_error_codes/error_codes/E0063.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0067.md (renamed from src/librustc_error_codes/error_codes/E0067.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0069.md (renamed from src/librustc_error_codes/error_codes/E0069.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0070.md (renamed from src/librustc_error_codes/error_codes/E0070.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0071.md (renamed from src/librustc_error_codes/error_codes/E0071.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0072.md (renamed from src/librustc_error_codes/error_codes/E0072.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0073.md (renamed from src/librustc_error_codes/error_codes/E0073.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0074.md (renamed from src/librustc_error_codes/error_codes/E0074.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0075.md (renamed from src/librustc_error_codes/error_codes/E0075.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0076.md (renamed from src/librustc_error_codes/error_codes/E0076.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0077.md (renamed from src/librustc_error_codes/error_codes/E0077.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0080.md (renamed from src/librustc_error_codes/error_codes/E0080.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0081.md (renamed from src/librustc_error_codes/error_codes/E0081.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0084.md (renamed from src/librustc_error_codes/error_codes/E0084.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0087.md (renamed from src/librustc_error_codes/error_codes/E0087.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0088.md (renamed from src/librustc_error_codes/error_codes/E0088.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0089.md (renamed from src/librustc_error_codes/error_codes/E0089.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0090.md (renamed from src/librustc_error_codes/error_codes/E0090.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0091.md (renamed from src/librustc_error_codes/error_codes/E0091.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0092.md (renamed from src/librustc_error_codes/error_codes/E0092.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0093.md (renamed from src/librustc_error_codes/error_codes/E0093.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0094.md (renamed from src/librustc_error_codes/error_codes/E0094.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0106.md (renamed from src/librustc_error_codes/error_codes/E0106.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0107.md (renamed from src/librustc_error_codes/error_codes/E0107.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0109.md (renamed from src/librustc_error_codes/error_codes/E0109.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0110.md (renamed from src/librustc_error_codes/error_codes/E0110.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0116.md (renamed from src/librustc_error_codes/error_codes/E0116.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0117.md (renamed from src/librustc_error_codes/error_codes/E0117.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0118.md (renamed from src/librustc_error_codes/error_codes/E0118.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0119.md (renamed from src/librustc_error_codes/error_codes/E0119.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0120.md (renamed from src/librustc_error_codes/error_codes/E0120.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0121.md (renamed from src/librustc_error_codes/error_codes/E0121.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0124.md (renamed from src/librustc_error_codes/error_codes/E0124.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0128.md (renamed from src/librustc_error_codes/error_codes/E0128.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0130.md (renamed from src/librustc_error_codes/error_codes/E0130.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0131.md (renamed from src/librustc_error_codes/error_codes/E0131.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0132.md (renamed from src/librustc_error_codes/error_codes/E0132.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0133.md (renamed from src/librustc_error_codes/error_codes/E0133.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0136.md (renamed from src/librustc_error_codes/error_codes/E0136.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0137.md (renamed from src/librustc_error_codes/error_codes/E0137.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0138.md (renamed from src/librustc_error_codes/error_codes/E0138.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0139.md (renamed from src/librustc_error_codes/error_codes/E0139.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0152.md (renamed from src/librustc_error_codes/error_codes/E0152.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0154.md (renamed from src/librustc_error_codes/error_codes/E0154.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0158.md (renamed from src/librustc_error_codes/error_codes/E0158.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0161.md (renamed from src/librustc_error_codes/error_codes/E0161.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0162.md (renamed from src/librustc_error_codes/error_codes/E0162.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0164.md (renamed from src/librustc_error_codes/error_codes/E0164.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0165.md (renamed from src/librustc_error_codes/error_codes/E0165.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0170.md (renamed from src/librustc_error_codes/error_codes/E0170.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0178.md (renamed from src/librustc_error_codes/error_codes/E0178.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0184.md (renamed from src/librustc_error_codes/error_codes/E0184.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0185.md (renamed from src/librustc_error_codes/error_codes/E0185.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0186.md (renamed from src/librustc_error_codes/error_codes/E0186.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0191.md (renamed from src/librustc_error_codes/error_codes/E0191.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0192.md (renamed from src/librustc_error_codes/error_codes/E0192.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0193.md (renamed from src/librustc_error_codes/error_codes/E0193.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0195.md (renamed from src/librustc_error_codes/error_codes/E0195.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0197.md (renamed from src/librustc_error_codes/error_codes/E0197.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0198.md (renamed from src/librustc_error_codes/error_codes/E0198.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0199.md (renamed from src/librustc_error_codes/error_codes/E0199.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0200.md (renamed from src/librustc_error_codes/error_codes/E0200.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0201.md (renamed from src/librustc_error_codes/error_codes/E0201.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0202.md (renamed from src/librustc_error_codes/error_codes/E0202.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0203.md (renamed from src/librustc_error_codes/error_codes/E0203.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0204.md (renamed from src/librustc_error_codes/error_codes/E0204.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0205.md (renamed from src/librustc_error_codes/error_codes/E0205.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0206.md (renamed from src/librustc_error_codes/error_codes/E0206.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0207.md (renamed from src/librustc_error_codes/error_codes/E0207.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0210.md (renamed from src/librustc_error_codes/error_codes/E0210.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0211.md (renamed from src/librustc_error_codes/error_codes/E0211.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0214.md (renamed from src/librustc_error_codes/error_codes/E0214.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0220.md (renamed from src/librustc_error_codes/error_codes/E0220.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0221.md (renamed from src/librustc_error_codes/error_codes/E0221.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0222.md (renamed from src/librustc_error_codes/error_codes/E0222.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0223.md (renamed from src/librustc_error_codes/error_codes/E0223.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0224.md (renamed from src/librustc_error_codes/error_codes/E0224.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0225.md (renamed from src/librustc_error_codes/error_codes/E0225.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0226.md (renamed from src/librustc_error_codes/error_codes/E0226.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0228.md (renamed from src/librustc_error_codes/error_codes/E0228.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0229.md (renamed from src/librustc_error_codes/error_codes/E0229.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0230.md (renamed from src/librustc_error_codes/error_codes/E0230.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0231.md (renamed from src/librustc_error_codes/error_codes/E0231.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0232.md (renamed from src/librustc_error_codes/error_codes/E0232.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0243.md (renamed from src/librustc_error_codes/error_codes/E0243.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0244.md (renamed from src/librustc_error_codes/error_codes/E0244.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0251.md (renamed from src/librustc_error_codes/error_codes/E0251.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0252.md (renamed from src/librustc_error_codes/error_codes/E0252.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0253.md (renamed from src/librustc_error_codes/error_codes/E0253.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0254.md (renamed from src/librustc_error_codes/error_codes/E0254.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0255.md (renamed from src/librustc_error_codes/error_codes/E0255.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0256.md (renamed from src/librustc_error_codes/error_codes/E0256.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0259.md (renamed from src/librustc_error_codes/error_codes/E0259.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0260.md (renamed from src/librustc_error_codes/error_codes/E0260.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0261.md (renamed from src/librustc_error_codes/error_codes/E0261.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0262.md (renamed from src/librustc_error_codes/error_codes/E0262.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0263.md (renamed from src/librustc_error_codes/error_codes/E0263.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0264.md (renamed from src/librustc_error_codes/error_codes/E0264.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0267.md (renamed from src/librustc_error_codes/error_codes/E0267.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0268.md (renamed from src/librustc_error_codes/error_codes/E0268.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0271.md (renamed from src/librustc_error_codes/error_codes/E0271.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0275.md (renamed from src/librustc_error_codes/error_codes/E0275.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0276.md (renamed from src/librustc_error_codes/error_codes/E0276.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0277.md (renamed from src/librustc_error_codes/error_codes/E0277.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0281.md (renamed from src/librustc_error_codes/error_codes/E0281.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0282.md (renamed from src/librustc_error_codes/error_codes/E0282.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0283.md (renamed from src/librustc_error_codes/error_codes/E0283.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0284.md (renamed from src/librustc_error_codes/error_codes/E0284.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0297.md (renamed from src/librustc_error_codes/error_codes/E0297.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0301.md (renamed from src/librustc_error_codes/error_codes/E0301.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0302.md (renamed from src/librustc_error_codes/error_codes/E0302.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0303.md (renamed from src/librustc_error_codes/error_codes/E0303.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0307.md (renamed from src/librustc_error_codes/error_codes/E0307.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0308.md (renamed from src/librustc_error_codes/error_codes/E0308.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0309.md (renamed from src/librustc_error_codes/error_codes/E0309.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0310.md (renamed from src/librustc_error_codes/error_codes/E0310.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0312.md (renamed from src/librustc_error_codes/error_codes/E0312.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0317.md (renamed from src/librustc_error_codes/error_codes/E0317.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0321.md (renamed from src/librustc_error_codes/error_codes/E0321.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0322.md (renamed from src/librustc_error_codes/error_codes/E0322.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0323.md (renamed from src/librustc_error_codes/error_codes/E0323.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0324.md (renamed from src/librustc_error_codes/error_codes/E0324.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0325.md (renamed from src/librustc_error_codes/error_codes/E0325.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0326.md (renamed from src/librustc_error_codes/error_codes/E0326.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0328.md (renamed from src/librustc_error_codes/error_codes/E0328.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0329.md (renamed from src/librustc_error_codes/error_codes/E0329.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0364.md (renamed from src/librustc_error_codes/error_codes/E0364.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0365.md (renamed from src/librustc_error_codes/error_codes/E0365.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0366.md (renamed from src/librustc_error_codes/error_codes/E0366.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0367.md (renamed from src/librustc_error_codes/error_codes/E0367.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0368.md (renamed from src/librustc_error_codes/error_codes/E0368.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0369.md (renamed from src/librustc_error_codes/error_codes/E0369.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0370.md (renamed from src/librustc_error_codes/error_codes/E0370.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0371.md (renamed from src/librustc_error_codes/error_codes/E0371.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0373.md (renamed from src/librustc_error_codes/error_codes/E0373.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0374.md (renamed from src/librustc_error_codes/error_codes/E0374.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0375.md (renamed from src/librustc_error_codes/error_codes/E0375.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0376.md (renamed from src/librustc_error_codes/error_codes/E0376.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0378.md (renamed from src/librustc_error_codes/error_codes/E0378.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0379.md (renamed from src/librustc_error_codes/error_codes/E0379.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0380.md (renamed from src/librustc_error_codes/error_codes/E0380.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0381.md (renamed from src/librustc_error_codes/error_codes/E0381.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0382.md (renamed from src/librustc_error_codes/error_codes/E0382.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0383.md (renamed from src/librustc_error_codes/error_codes/E0383.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0384.md (renamed from src/librustc_error_codes/error_codes/E0384.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0386.md (renamed from src/librustc_error_codes/error_codes/E0386.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0387.md (renamed from src/librustc_error_codes/error_codes/E0387.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0388.md (renamed from src/librustc_error_codes/error_codes/E0388.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0389.md (renamed from src/librustc_error_codes/error_codes/E0389.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0390.md (renamed from src/librustc_error_codes/error_codes/E0390.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0391.md (renamed from src/librustc_error_codes/error_codes/E0391.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0392.md (renamed from src/librustc_error_codes/error_codes/E0392.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0393.md (renamed from src/librustc_error_codes/error_codes/E0393.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0398.md (renamed from src/librustc_error_codes/error_codes/E0398.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0399.md (renamed from src/librustc_error_codes/error_codes/E0399.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0401.md (renamed from src/librustc_error_codes/error_codes/E0401.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0403.md (renamed from src/librustc_error_codes/error_codes/E0403.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0404.md (renamed from src/librustc_error_codes/error_codes/E0404.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0405.md (renamed from src/librustc_error_codes/error_codes/E0405.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0407.md (renamed from src/librustc_error_codes/error_codes/E0407.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0408.md (renamed from src/librustc_error_codes/error_codes/E0408.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0409.md (renamed from src/librustc_error_codes/error_codes/E0409.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0411.md (renamed from src/librustc_error_codes/error_codes/E0411.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0412.md (renamed from src/librustc_error_codes/error_codes/E0412.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0415.md (renamed from src/librustc_error_codes/error_codes/E0415.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0416.md (renamed from src/librustc_error_codes/error_codes/E0416.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0422.md (renamed from src/librustc_error_codes/error_codes/E0422.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0423.md (renamed from src/librustc_error_codes/error_codes/E0423.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0424.md (renamed from src/librustc_error_codes/error_codes/E0424.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0425.md (renamed from src/librustc_error_codes/error_codes/E0425.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0426.md (renamed from src/librustc_error_codes/error_codes/E0426.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0428.md (renamed from src/librustc_error_codes/error_codes/E0428.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0429.md (renamed from src/librustc_error_codes/error_codes/E0429.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0430.md (renamed from src/librustc_error_codes/error_codes/E0430.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0431.md (renamed from src/librustc_error_codes/error_codes/E0431.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0432.md (renamed from src/librustc_error_codes/error_codes/E0432.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0433.md (renamed from src/librustc_error_codes/error_codes/E0433.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0434.md (renamed from src/librustc_error_codes/error_codes/E0434.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0435.md (renamed from src/librustc_error_codes/error_codes/E0435.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0436.md (renamed from src/librustc_error_codes/error_codes/E0436.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0437.md (renamed from src/librustc_error_codes/error_codes/E0437.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0438.md (renamed from src/librustc_error_codes/error_codes/E0438.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0439.md (renamed from src/librustc_error_codes/error_codes/E0439.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0445.md (renamed from src/librustc_error_codes/error_codes/E0445.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0446.md (renamed from src/librustc_error_codes/error_codes/E0446.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0447.md (renamed from src/librustc_error_codes/error_codes/E0447.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0448.md (renamed from src/librustc_error_codes/error_codes/E0448.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0449.md (renamed from src/librustc_error_codes/error_codes/E0449.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0451.md (renamed from src/librustc_error_codes/error_codes/E0451.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0452.md (renamed from src/librustc_error_codes/error_codes/E0452.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0453.md (renamed from src/librustc_error_codes/error_codes/E0453.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0454.md (renamed from src/librustc_error_codes/error_codes/E0454.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0455.md (renamed from src/librustc_error_codes/error_codes/E0455.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0458.md (renamed from src/librustc_error_codes/error_codes/E0458.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0459.md (renamed from src/librustc_error_codes/error_codes/E0459.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0463.md (renamed from src/librustc_error_codes/error_codes/E0463.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0466.md (renamed from src/librustc_error_codes/error_codes/E0466.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0468.md (renamed from src/librustc_error_codes/error_codes/E0468.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0469.md (renamed from src/librustc_error_codes/error_codes/E0469.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0477.md (renamed from src/librustc_error_codes/error_codes/E0477.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0478.md (renamed from src/librustc_error_codes/error_codes/E0478.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0491.md (renamed from src/librustc_error_codes/error_codes/E0491.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0492.md (renamed from src/librustc_error_codes/error_codes/E0492.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0493.md (renamed from src/librustc_error_codes/error_codes/E0493.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0495.md (renamed from src/librustc_error_codes/error_codes/E0495.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0496.md (renamed from src/librustc_error_codes/error_codes/E0496.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0497.md (renamed from src/librustc_error_codes/error_codes/E0497.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0499.md (renamed from src/librustc_error_codes/error_codes/E0499.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0500.md (renamed from src/librustc_error_codes/error_codes/E0500.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0501.md (renamed from src/librustc_error_codes/error_codes/E0501.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0502.md (renamed from src/librustc_error_codes/error_codes/E0502.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0503.md (renamed from src/librustc_error_codes/error_codes/E0503.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0504.md (renamed from src/librustc_error_codes/error_codes/E0504.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0505.md (renamed from src/librustc_error_codes/error_codes/E0505.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0506.md (renamed from src/librustc_error_codes/error_codes/E0506.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0507.md (renamed from src/librustc_error_codes/error_codes/E0507.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0508.md (renamed from src/librustc_error_codes/error_codes/E0508.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0509.md (renamed from src/librustc_error_codes/error_codes/E0509.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0510.md (renamed from src/librustc_error_codes/error_codes/E0510.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0511.md (renamed from src/librustc_error_codes/error_codes/E0511.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0512.md (renamed from src/librustc_error_codes/error_codes/E0512.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0515.md (renamed from src/librustc_error_codes/error_codes/E0515.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0516.md (renamed from src/librustc_error_codes/error_codes/E0516.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0517.md (renamed from src/librustc_error_codes/error_codes/E0517.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0518.md (renamed from src/librustc_error_codes/error_codes/E0518.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0520.md (renamed from src/librustc_error_codes/error_codes/E0520.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0522.md (renamed from src/librustc_error_codes/error_codes/E0522.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0524.md (renamed from src/librustc_error_codes/error_codes/E0524.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0525.md (renamed from src/librustc_error_codes/error_codes/E0525.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0527.md (renamed from src/librustc_error_codes/error_codes/E0527.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0528.md (renamed from src/librustc_error_codes/error_codes/E0528.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0529.md (renamed from src/librustc_error_codes/error_codes/E0529.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0530.md (renamed from src/librustc_error_codes/error_codes/E0530.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0531.md (renamed from src/librustc_error_codes/error_codes/E0531.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0532.md (renamed from src/librustc_error_codes/error_codes/E0532.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0533.md (renamed from src/librustc_error_codes/error_codes/E0533.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0534.md (renamed from src/librustc_error_codes/error_codes/E0534.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0535.md (renamed from src/librustc_error_codes/error_codes/E0535.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0536.md (renamed from src/librustc_error_codes/error_codes/E0536.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0537.md (renamed from src/librustc_error_codes/error_codes/E0537.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0538.md (renamed from src/librustc_error_codes/error_codes/E0538.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0539.md (renamed from src/librustc_error_codes/error_codes/E0539.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0541.md (renamed from src/librustc_error_codes/error_codes/E0541.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0550.md (renamed from src/librustc_error_codes/error_codes/E0550.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0551.md (renamed from src/librustc_error_codes/error_codes/E0551.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0552.md (renamed from src/librustc_error_codes/error_codes/E0552.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0554.md (renamed from src/librustc_error_codes/error_codes/E0554.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0556.md (renamed from src/librustc_error_codes/error_codes/E0556.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0557.md (renamed from src/librustc_error_codes/error_codes/E0557.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0559.md (renamed from src/librustc_error_codes/error_codes/E0559.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0560.md (renamed from src/librustc_error_codes/error_codes/E0560.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0561.md (renamed from src/librustc_error_codes/error_codes/E0561.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0562.md (renamed from src/librustc_error_codes/error_codes/E0562.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0565.md (renamed from src/librustc_error_codes/error_codes/E0565.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0566.md (renamed from src/librustc_error_codes/error_codes/E0566.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0567.md (renamed from src/librustc_error_codes/error_codes/E0567.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0568.md (renamed from src/librustc_error_codes/error_codes/E0568.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0569.md (renamed from src/librustc_error_codes/error_codes/E0569.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0570.md (renamed from src/librustc_error_codes/error_codes/E0570.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0571.md (renamed from src/librustc_error_codes/error_codes/E0571.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0572.md (renamed from src/librustc_error_codes/error_codes/E0572.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0573.md (renamed from src/librustc_error_codes/error_codes/E0573.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0574.md (renamed from src/librustc_error_codes/error_codes/E0574.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0575.md (renamed from src/librustc_error_codes/error_codes/E0575.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0576.md (renamed from src/librustc_error_codes/error_codes/E0576.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0577.md (renamed from src/librustc_error_codes/error_codes/E0577.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0578.md (renamed from src/librustc_error_codes/error_codes/E0578.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0579.md (renamed from src/librustc_error_codes/error_codes/E0579.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0580.md (renamed from src/librustc_error_codes/error_codes/E0580.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0581.md (renamed from src/librustc_error_codes/error_codes/E0581.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0582.md (renamed from src/librustc_error_codes/error_codes/E0582.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0583.md (renamed from src/librustc_error_codes/error_codes/E0583.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0584.md (renamed from src/librustc_error_codes/error_codes/E0584.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0585.md (renamed from src/librustc_error_codes/error_codes/E0585.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0586.md (renamed from src/librustc_error_codes/error_codes/E0586.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0587.md (renamed from src/librustc_error_codes/error_codes/E0587.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0588.md (renamed from src/librustc_error_codes/error_codes/E0588.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0589.md (renamed from src/librustc_error_codes/error_codes/E0589.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0590.md (renamed from src/librustc_error_codes/error_codes/E0590.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0591.md (renamed from src/librustc_error_codes/error_codes/E0591.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0592.md (renamed from src/librustc_error_codes/error_codes/E0592.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0593.md (renamed from src/librustc_error_codes/error_codes/E0593.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0594.md (renamed from src/librustc_error_codes/error_codes/E0594.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0595.md (renamed from src/librustc_error_codes/error_codes/E0595.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0596.md (renamed from src/librustc_error_codes/error_codes/E0596.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0597.md (renamed from src/librustc_error_codes/error_codes/E0597.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0599.md (renamed from src/librustc_error_codes/error_codes/E0599.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0600.md (renamed from src/librustc_error_codes/error_codes/E0600.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0601.md (renamed from src/librustc_error_codes/error_codes/E0601.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0602.md (renamed from src/librustc_error_codes/error_codes/E0602.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0603.md (renamed from src/librustc_error_codes/error_codes/E0603.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0604.md (renamed from src/librustc_error_codes/error_codes/E0604.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0605.md (renamed from src/librustc_error_codes/error_codes/E0605.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0606.md (renamed from src/librustc_error_codes/error_codes/E0606.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0607.md (renamed from src/librustc_error_codes/error_codes/E0607.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0608.md (renamed from src/librustc_error_codes/error_codes/E0608.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0609.md (renamed from src/librustc_error_codes/error_codes/E0609.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0610.md (renamed from src/librustc_error_codes/error_codes/E0610.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0614.md (renamed from src/librustc_error_codes/error_codes/E0614.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0615.md (renamed from src/librustc_error_codes/error_codes/E0615.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0616.md (renamed from src/librustc_error_codes/error_codes/E0616.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0617.md (renamed from src/librustc_error_codes/error_codes/E0617.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0618.md (renamed from src/librustc_error_codes/error_codes/E0618.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0619.md (renamed from src/librustc_error_codes/error_codes/E0619.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0620.md (renamed from src/librustc_error_codes/error_codes/E0620.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0621.md (renamed from src/librustc_error_codes/error_codes/E0621.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0622.md (renamed from src/librustc_error_codes/error_codes/E0622.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0623.md (renamed from src/librustc_error_codes/error_codes/E0623.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0624.md (renamed from src/librustc_error_codes/error_codes/E0624.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0626.md (renamed from src/librustc_error_codes/error_codes/E0626.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0627.md (renamed from src/librustc_error_codes/error_codes/E0627.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0628.md (renamed from src/librustc_error_codes/error_codes/E0628.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0631.md (renamed from src/librustc_error_codes/error_codes/E0631.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0633.md (renamed from src/librustc_error_codes/error_codes/E0633.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0634.md (renamed from src/librustc_error_codes/error_codes/E0634.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0635.md (renamed from src/librustc_error_codes/error_codes/E0635.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0636.md (renamed from src/librustc_error_codes/error_codes/E0636.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0637.md (renamed from src/librustc_error_codes/error_codes/E0637.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0638.md (renamed from src/librustc_error_codes/error_codes/E0638.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0639.md (renamed from src/librustc_error_codes/error_codes/E0639.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0641.md (renamed from src/librustc_error_codes/error_codes/E0641.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0642.md (renamed from src/librustc_error_codes/error_codes/E0642.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0643.md (renamed from src/librustc_error_codes/error_codes/E0643.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0644.md (renamed from src/librustc_error_codes/error_codes/E0644.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0646.md (renamed from src/librustc_error_codes/error_codes/E0646.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0647.md (renamed from src/librustc_error_codes/error_codes/E0647.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0648.md (renamed from src/librustc_error_codes/error_codes/E0648.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0657.md (renamed from src/librustc_error_codes/error_codes/E0657.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0658.md (renamed from src/librustc_error_codes/error_codes/E0658.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0659.md (renamed from src/librustc_error_codes/error_codes/E0659.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0660.md (renamed from src/librustc_error_codes/error_codes/E0660.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0661.md (renamed from src/librustc_error_codes/error_codes/E0661.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0662.md (renamed from src/librustc_error_codes/error_codes/E0662.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0663.md (renamed from src/librustc_error_codes/error_codes/E0663.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0664.md (renamed from src/librustc_error_codes/error_codes/E0664.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0665.md (renamed from src/librustc_error_codes/error_codes/E0665.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0666.md (renamed from src/librustc_error_codes/error_codes/E0666.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0668.md (renamed from src/librustc_error_codes/error_codes/E0668.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0669.md (renamed from src/librustc_error_codes/error_codes/E0669.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0670.md (renamed from src/librustc_error_codes/error_codes/E0670.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0671.md (renamed from src/librustc_error_codes/error_codes/E0671.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0687.md (renamed from src/librustc_error_codes/error_codes/E0687.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0688.md (renamed from src/librustc_error_codes/error_codes/E0688.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0689.md (renamed from src/librustc_error_codes/error_codes/E0689.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0690.md (renamed from src/librustc_error_codes/error_codes/E0690.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0691.md (renamed from src/librustc_error_codes/error_codes/E0691.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0692.md (renamed from src/librustc_error_codes/error_codes/E0692.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0693.md (renamed from src/librustc_error_codes/error_codes/E0693.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0695.md (renamed from src/librustc_error_codes/error_codes/E0695.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0696.md (renamed from src/librustc_error_codes/error_codes/E0696.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0697.md (renamed from src/librustc_error_codes/error_codes/E0697.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0698.md (renamed from src/librustc_error_codes/error_codes/E0698.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0699.md (renamed from src/librustc_error_codes/error_codes/E0699.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0700.md (renamed from src/librustc_error_codes/error_codes/E0700.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0701.md (renamed from src/librustc_error_codes/error_codes/E0701.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0703.md (renamed from src/librustc_error_codes/error_codes/E0703.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0704.md (renamed from src/librustc_error_codes/error_codes/E0704.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0705.md (renamed from src/librustc_error_codes/error_codes/E0705.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0706.md (renamed from src/librustc_error_codes/error_codes/E0706.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0708.md (renamed from src/librustc_error_codes/error_codes/E0708.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0710.md (renamed from src/librustc_error_codes/error_codes/E0710.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0712.md (renamed from src/librustc_error_codes/error_codes/E0712.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0713.md (renamed from src/librustc_error_codes/error_codes/E0713.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0714.md (renamed from src/librustc_error_codes/error_codes/E0714.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0715.md (renamed from src/librustc_error_codes/error_codes/E0715.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0716.md (renamed from src/librustc_error_codes/error_codes/E0716.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0718.md (renamed from src/librustc_error_codes/error_codes/E0718.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0719.md (renamed from src/librustc_error_codes/error_codes/E0719.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0720.md (renamed from src/librustc_error_codes/error_codes/E0720.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0723.md (renamed from src/librustc_error_codes/error_codes/E0723.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0724.md (renamed from src/librustc_error_codes/error_codes/E0724.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0725.md (renamed from src/librustc_error_codes/error_codes/E0725.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0727.md (renamed from src/librustc_error_codes/error_codes/E0727.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0728.md (renamed from src/librustc_error_codes/error_codes/E0728.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0729.md (renamed from src/librustc_error_codes/error_codes/E0729.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0730.md (renamed from src/librustc_error_codes/error_codes/E0730.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0731.md (renamed from src/librustc_error_codes/error_codes/E0731.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0732.md (renamed from src/librustc_error_codes/error_codes/E0732.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0733.md (renamed from src/librustc_error_codes/error_codes/E0733.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0734.md (renamed from src/librustc_error_codes/error_codes/E0734.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0735.md (renamed from src/librustc_error_codes/error_codes/E0735.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0736.md (renamed from src/librustc_error_codes/error_codes/E0736.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0737.md (renamed from src/librustc_error_codes/error_codes/E0737.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0739.md (renamed from src/librustc_error_codes/error_codes/E0739.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0740.md (renamed from src/librustc_error_codes/error_codes/E0740.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0741.md (renamed from src/librustc_error_codes/error_codes/E0741.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0742.md (renamed from src/librustc_error_codes/error_codes/E0742.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0743.md (renamed from src/librustc_error_codes/error_codes/E0743.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0744.md (renamed from src/librustc_error_codes/error_codes/E0744.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0745.md (renamed from src/librustc_error_codes/error_codes/E0745.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0746.md (renamed from src/librustc_error_codes/error_codes/E0746.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0747.md (renamed from src/librustc_error_codes/error_codes/E0747.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0748.md (renamed from src/librustc_error_codes/error_codes/E0748.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0749.md (renamed from src/librustc_error_codes/error_codes/E0749.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0750.md (renamed from src/librustc_error_codes/error_codes/E0750.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0751.md (renamed from src/librustc_error_codes/error_codes/E0751.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0752.md (renamed from src/librustc_error_codes/error_codes/E0752.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0753.md (renamed from src/librustc_error_codes/error_codes/E0753.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0754.md (renamed from src/librustc_error_codes/error_codes/E0754.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0758.md (renamed from src/librustc_error_codes/error_codes/E0758.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0759.md (renamed from src/librustc_error_codes/error_codes/E0759.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0760.md (renamed from src/librustc_error_codes/error_codes/E0760.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0761.md (renamed from src/librustc_error_codes/error_codes/E0761.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0762.md (renamed from src/librustc_error_codes/error_codes/E0762.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0763.md (renamed from src/librustc_error_codes/error_codes/E0763.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0764.md (renamed from src/librustc_error_codes/error_codes/E0764.md) | 22 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0765.md (renamed from src/librustc_error_codes/error_codes/E0765.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0766.md (renamed from src/librustc_error_codes/error_codes/E0766.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0767.md (renamed from src/librustc_error_codes/error_codes/E0767.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0768.md (renamed from src/librustc_error_codes/error_codes/E0768.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0769.md (renamed from src/librustc_error_codes/error_codes/E0769.md) | 22 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0770.md (renamed from src/librustc_error_codes/error_codes/E0770.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0771.md (renamed from src/librustc_error_codes/error_codes/E0771.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0773.md | 38 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/lib.rs (renamed from src/librustc_error_codes/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/Cargo.toml (renamed from src/librustc_errors/Cargo.toml) | 10 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs (renamed from src/librustc_errors/annotate_snippet_emitter_writer.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs (renamed from src/librustc_errors/diagnostic.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_builder.rs (renamed from src/librustc_errors/diagnostic_builder.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/emitter.rs (renamed from src/librustc_errors/emitter.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/json.rs (renamed from src/librustc_errors/json.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/json/tests.rs (renamed from src/librustc_errors/json/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs (renamed from src/librustc_errors/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lock.rs (renamed from src/librustc_errors/lock.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/registry.rs (renamed from src/librustc_errors/registry.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/snippet.rs (renamed from src/librustc_errors/snippet.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/styled_buffer.rs (renamed from src/librustc_errors/styled_buffer.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/Cargo.toml | 26 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/base.rs (renamed from src/librustc_expand/base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/build.rs (renamed from src/librustc_expand/build.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/config.rs (renamed from src/librustc_expand/config.rs) | 11 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/expand.rs (renamed from src/librustc_expand/expand.rs) | 6 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/lib.rs (renamed from src/librustc_expand/lib.rs) | 5 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe.rs (renamed from src/librustc_expand/mbe.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe/macro_check.rs (renamed from src/librustc_expand/mbe/macro_check.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe/macro_parser.rs (renamed from src/librustc_expand/mbe/macro_parser.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe/macro_rules.rs (renamed from src/librustc_expand/mbe/macro_rules.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe/quoted.rs (renamed from src/librustc_expand/mbe/quoted.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe/transcribe.rs (renamed from src/librustc_expand/mbe/transcribe.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/module.rs (renamed from src/librustc_expand/module.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mut_visit/tests.rs (renamed from src/librustc_expand/mut_visit/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/parse/tests.rs (renamed from src/librustc_expand/parse/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/placeholders.rs (renamed from src/librustc_expand/placeholders.rs) | 8 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/proc_macro.rs (renamed from src/librustc_expand/proc_macro.rs) | 41 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/proc_macro_server.rs (renamed from src/librustc_expand/proc_macro_server.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/tests.rs (renamed from src/librustc_expand/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/tokenstream/tests.rs (renamed from src/librustc_expand/tokenstream/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_feature/Cargo.toml | 12 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/accepted.rs (renamed from src/librustc_feature/accepted.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/active.rs (renamed from src/librustc_feature/active.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs (renamed from src/librustc_feature/builtin_attrs.rs) | 10 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/lib.rs (renamed from src/librustc_feature/lib.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/removed.rs (renamed from src/librustc_feature/removed.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_fs_util/Cargo.toml (renamed from src/librustc_fs_util/Cargo.toml) | 6 | ||||
| -rw-r--r-- | compiler/rustc_fs_util/src/lib.rs (renamed from src/librustc_fs_util/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_graphviz/Cargo.toml (renamed from src/librustc_graphviz/Cargo.toml) | 4 | ||||
| -rw-r--r-- | compiler/rustc_graphviz/src/lib.rs (renamed from src/librustc_graphviz/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_graphviz/src/tests.rs (renamed from src/librustc_graphviz/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/Cargo.toml | 19 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/arena.rs (renamed from src/librustc_hir/arena.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/def.rs (renamed from src/librustc_hir/def.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/definitions.rs (renamed from src/librustc_hir/definitions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs (renamed from src/librustc_hir/hir.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir_id.rs (renamed from src/librustc_hir/hir_id.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/intravisit.rs (renamed from src/librustc_hir/intravisit.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/itemlikevisit.rs (renamed from src/librustc_hir/itemlikevisit.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/lang_items.rs (renamed from src/librustc_hir/lang_items.rs) | 16 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/lib.rs (renamed from src/librustc_hir/lib.rs) | 1 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/pat_util.rs (renamed from src/librustc_hir/pat_util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/stable_hash_impls.rs (renamed from src/librustc_hir/stable_hash_impls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/target.rs (renamed from src/librustc_hir/target.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/weak_lang_items.rs (renamed from src/librustc_hir/weak_lang_items.rs) | 14 | ||||
| -rw-r--r-- | compiler/rustc_hir_pretty/Cargo.toml | 15 | ||||
| -rw-r--r-- | compiler/rustc_hir_pretty/src/lib.rs (renamed from src/librustc_hir_pretty/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/Cargo.toml | 22 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/assert_dep_graph.rs (renamed from src/librustc_incremental/assert_dep_graph.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/assert_module_sources.rs (renamed from src/librustc_incremental/assert_module_sources.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/lib.rs (renamed from src/librustc_incremental/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/README.md (renamed from src/librustc_incremental/persist/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/data.rs (renamed from src/librustc_incremental/persist/data.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/dirty_clean.rs (renamed from src/librustc_incremental/persist/dirty_clean.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/file_format.rs (renamed from src/librustc_incremental/persist/file_format.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/fs.rs (renamed from src/librustc_incremental/persist/fs.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/fs/tests.rs (renamed from src/librustc_incremental/persist/fs/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/load.rs (renamed from src/librustc_incremental/persist/load.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/mod.rs (renamed from src/librustc_incremental/persist/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/save.rs (renamed from src/librustc_incremental/persist/save.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_incremental/src/persist/work_product.rs (renamed from src/librustc_incremental/persist/work_product.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_index/Cargo.toml (renamed from src/librustc_index/Cargo.toml) | 6 | ||||
| -rw-r--r-- | compiler/rustc_index/src/bit_set.rs (renamed from src/librustc_index/bit_set.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_index/src/bit_set/tests.rs (renamed from src/librustc_index/bit_set/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_index/src/lib.rs (renamed from src/librustc_index/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_index/src/vec.rs (renamed from src/librustc_index/vec.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_index/src/vec/tests.rs (renamed from src/librustc_index/vec/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/Cargo.toml | 24 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/at.rs (renamed from src/librustc_infer/infer/at.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/canonicalizer.rs (renamed from src/librustc_infer/infer/canonical/canonicalizer.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/mod.rs (renamed from src/librustc_infer/infer/canonical/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/query_response.rs (renamed from src/librustc_infer/infer/canonical/query_response.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/substitute.rs (renamed from src/librustc_infer/infer/canonical/substitute.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/combine.rs (renamed from src/librustc_infer/infer/combine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/equate.rs (renamed from src/librustc_infer/infer/equate.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/mod.rs (renamed from src/librustc_infer/infer/error_reporting/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs (renamed from src/librustc_infer/infer/error_reporting/need_type_info.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs (renamed from src/librustc_infer/infer/error_reporting/nice_region_error/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/note.rs (renamed from src/librustc_infer/infer/error_reporting/note.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/free_regions.rs (renamed from src/librustc_infer/infer/free_regions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/freshen.rs (renamed from src/librustc_infer/infer/freshen.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/fudge.rs (renamed from src/librustc_infer/infer/fudge.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/glb.rs (renamed from src/librustc_infer/infer/glb.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/higher_ranked/README.md (renamed from src/librustc_infer/infer/higher_ranked/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/higher_ranked/mod.rs (renamed from src/librustc_infer/infer/higher_ranked/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/lattice.rs (renamed from src/librustc_infer/infer/lattice.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/lexical_region_resolve/README.md (renamed from src/librustc_infer/infer/lexical_region_resolve/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs (renamed from src/librustc_infer/infer/lexical_region_resolve/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/lub.rs (renamed from src/librustc_infer/infer/lub.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs (renamed from src/librustc_infer/infer/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/nll_relate/mod.rs (renamed from src/librustc_infer/infer/nll_relate/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/outlives/env.rs (renamed from src/librustc_infer/infer/outlives/env.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/outlives/mod.rs (renamed from src/librustc_infer/infer/outlives/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/outlives/obligations.rs (renamed from src/librustc_infer/infer/outlives/obligations.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/outlives/verify.rs (renamed from src/librustc_infer/infer/outlives/verify.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/region_constraints/README.md (renamed from src/librustc_infer/infer/region_constraints/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/region_constraints/leak_check.rs (renamed from src/librustc_infer/infer/region_constraints/leak_check.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/region_constraints/mod.rs (renamed from src/librustc_infer/infer/region_constraints/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/resolve.rs (renamed from src/librustc_infer/infer/resolve.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/sub.rs (renamed from src/librustc_infer/infer/sub.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/type_variable.rs (renamed from src/librustc_infer/infer/type_variable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/undo_log.rs (renamed from src/librustc_infer/infer/undo_log.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/lib.rs (renamed from src/librustc_infer/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/engine.rs (renamed from src/librustc_infer/traits/engine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/error_reporting/mod.rs (renamed from src/librustc_infer/traits/error_reporting/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/mod.rs (renamed from src/librustc_infer/traits/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/project.rs (renamed from src/librustc_infer/traits/project.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/structural_impls.rs (renamed from src/librustc_infer/traits/structural_impls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/traits/util.rs (renamed from src/librustc_infer/traits/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_interface/Cargo.toml | 54 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/callbacks.rs (renamed from src/librustc_interface/callbacks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs (renamed from src/librustc_interface/interface.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/lib.rs (renamed from src/librustc_interface/lib.rs) | 1 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs (renamed from src/librustc_interface/passes.rs) | 7 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/proc_macro_decls.rs (renamed from src/librustc_interface/proc_macro_decls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/queries.rs (renamed from src/librustc_interface/queries.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/tests.rs (renamed from src/librustc_interface/tests.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/util.rs (renamed from src/librustc_interface/util.rs) | 4 | ||||
| -rw-r--r-- | compiler/rustc_lexer/Cargo.toml (renamed from src/librustc_lexer/Cargo.toml) | 3 | ||||
| -rw-r--r-- | compiler/rustc_lexer/src/cursor.rs (renamed from src/librustc_lexer/src/cursor.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lexer/src/lib.rs (renamed from src/librustc_lexer/src/lib.rs) | 14 | ||||
| -rw-r--r-- | compiler/rustc_lexer/src/tests.rs | 287 | ||||
| -rw-r--r-- | compiler/rustc_lexer/src/unescape.rs (renamed from src/librustc_lexer/src/unescape.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lexer/src/unescape/tests.rs (renamed from src/librustc_lexer/src/unescape/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/Cargo.toml | 22 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/array_into_iter.rs (renamed from src/librustc_lint/array_into_iter.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs (renamed from src/librustc_lint/builtin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs (renamed from src/librustc_lint/context.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/early.rs (renamed from src/librustc_lint/early.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/internal.rs (renamed from src/librustc_lint/internal.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/late.rs (renamed from src/librustc_lint/late.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/levels.rs (renamed from src/librustc_lint/levels.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs (renamed from src/librustc_lint/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/non_ascii_idents.rs (renamed from src/librustc_lint/non_ascii_idents.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/nonstandard_style.rs (renamed from src/librustc_lint/nonstandard_style.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/nonstandard_style/tests.rs (renamed from src/librustc_lint/nonstandard_style/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/passes.rs (renamed from src/librustc_lint/passes.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/redundant_semicolon.rs (renamed from src/librustc_lint/redundant_semicolon.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/types.rs (renamed from src/librustc_lint/types.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/unused.rs (renamed from src/librustc_lint/unused.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/Cargo.toml (renamed from src/librustc_macros/Cargo.toml) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/hash_stable.rs (renamed from src/librustc_macros/src/hash_stable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/lib.rs (renamed from src/librustc_macros/src/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/lift.rs (renamed from src/librustc_macros/src/lift.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/query.rs (renamed from src/librustc_macros/src/query.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/serialize.rs (renamed from src/librustc_macros/src/serialize.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/symbols.rs (renamed from src/librustc_macros/src/symbols.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/type_foldable.rs (renamed from src/librustc_macros/src/type_foldable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/Cargo.toml | 33 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/creader.rs (renamed from src/librustc_metadata/creader.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/dependency_format.rs (renamed from src/librustc_metadata/dependency_format.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/dynamic_lib.rs (renamed from src/librustc_metadata/dynamic_lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/dynamic_lib/tests.rs (renamed from src/librustc_metadata/dynamic_lib/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/foreign_modules.rs (renamed from src/librustc_metadata/foreign_modules.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/lib.rs (renamed from src/librustc_metadata/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/link_args.rs (renamed from src/librustc_metadata/link_args.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/locator.rs (renamed from src/librustc_metadata/locator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/native_libs.rs (renamed from src/librustc_metadata/native_libs.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs (renamed from src/librustc_metadata/rmeta/decoder.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs (renamed from src/librustc_metadata/rmeta/decoder/cstore_impl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs (renamed from src/librustc_metadata/rmeta/encoder.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/mod.rs (renamed from src/librustc_metadata/rmeta/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/table.rs (renamed from src/librustc_metadata/rmeta/table.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/Cargo.toml | 33 | ||||
| -rw-r--r-- | compiler/rustc_middle/README.md (renamed from src/librustc_middle/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/benches/lib.rs (renamed from src/librustc_middle/benches/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/arena.rs (renamed from src/librustc_middle/arena.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/dep_graph/dep_node.rs (renamed from src/librustc_middle/dep_graph/dep_node.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/dep_graph/mod.rs (renamed from src/librustc_middle/dep_graph/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/exports.rs (renamed from src/librustc_middle/hir/exports.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/blocks.rs (renamed from src/librustc_middle/hir/map/blocks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/collector.rs (renamed from src/librustc_middle/hir/map/collector.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/mod.rs (renamed from src/librustc_middle/hir/map/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/mod.rs (renamed from src/librustc_middle/hir/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/place.rs (renamed from src/librustc_middle/hir/place.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ich/hcx.rs (renamed from src/librustc_middle/ich/hcx.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ich/impls_hir.rs (renamed from src/librustc_middle/ich/impls_hir.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ich/impls_syntax.rs (renamed from src/librustc_middle/ich/impls_syntax.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ich/impls_ty.rs (renamed from src/librustc_middle/ich/impls_ty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ich/mod.rs (renamed from src/librustc_middle/ich/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/infer/canonical.rs (renamed from src/librustc_middle/infer/canonical.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/infer/mod.rs (renamed from src/librustc_middle/infer/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/infer/unify_key.rs (renamed from src/librustc_middle/infer/unify_key.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/lib.rs (renamed from src/librustc_middle/lib.rs) | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/lint.rs (renamed from src/librustc_middle/lint.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/macros.rs (renamed from src/librustc_middle/macros.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/codegen_fn_attrs.rs (renamed from src/librustc_middle/middle/codegen_fn_attrs.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/cstore.rs (renamed from src/librustc_middle/middle/cstore.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/dependency_format.rs (renamed from src/librustc_middle/middle/dependency_format.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/exported_symbols.rs (renamed from src/librustc_middle/middle/exported_symbols.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/lang_items.rs (renamed from src/librustc_middle/middle/lang_items.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/limits.rs (renamed from src/librustc_middle/middle/limits.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/mod.rs (renamed from src/librustc_middle/middle/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/privacy.rs (renamed from src/librustc_middle/middle/privacy.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/region.rs (renamed from src/librustc_middle/middle/region.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/resolve_lifetime.rs (renamed from src/librustc_middle/middle/resolve_lifetime.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/stability.rs (renamed from src/librustc_middle/middle/stability.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/coverage/mod.rs (renamed from src/librustc_middle/mir/coverage/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/allocation.rs (renamed from src/librustc_middle/mir/interpret/allocation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs (renamed from src/librustc_middle/mir/interpret/error.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/mod.rs (renamed from src/librustc_middle/mir/interpret/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/pointer.rs (renamed from src/librustc_middle/mir/interpret/pointer.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/queries.rs (renamed from src/librustc_middle/mir/interpret/queries.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/value.rs (renamed from src/librustc_middle/mir/interpret/value.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs (renamed from src/librustc_middle/mir/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mono.rs (renamed from src/librustc_middle/mir/mono.rs) | 39 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/predecessors.rs (renamed from src/librustc_middle/mir/predecessors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/query.rs (renamed from src/librustc_middle/mir/query.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/tcx.rs (renamed from src/librustc_middle/mir/tcx.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/terminator/mod.rs (renamed from src/librustc_middle/mir/terminator/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/traversal.rs (renamed from src/librustc_middle/mir/traversal.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/type_foldable.rs (renamed from src/librustc_middle/mir/type_foldable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs (renamed from src/librustc_middle/mir/visit.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs (renamed from src/librustc_middle/query/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/tests.rs (renamed from src/librustc_middle/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/chalk.rs (renamed from src/librustc_middle/traits/chalk.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs (renamed from src/librustc_middle/traits/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/query.rs (renamed from src/librustc_middle/traits/query.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/select.rs (renamed from src/librustc_middle/traits/select.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/specialization_graph.rs (renamed from src/librustc_middle/traits/specialization_graph.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/structural_impls.rs (renamed from src/librustc_middle/traits/structural_impls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/_match.rs (renamed from src/librustc_middle/ty/_match.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/adjustment.rs (renamed from src/librustc_middle/ty/adjustment.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/binding.rs (renamed from src/librustc_middle/ty/binding.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/cast.rs (renamed from src/librustc_middle/ty/cast.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/codec.rs (renamed from src/librustc_middle/ty/codec.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts.rs (renamed from src/librustc_middle/ty/consts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/int.rs (renamed from src/librustc_middle/ty/consts/int.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts/kind.rs (renamed from src/librustc_middle/ty/consts/kind.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs (renamed from src/librustc_middle/ty/context.rs) | 5 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/diagnostics.rs (renamed from src/librustc_middle/ty/diagnostics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/erase_regions.rs (renamed from src/librustc_middle/ty/erase_regions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/error.rs (renamed from src/librustc_middle/ty/error.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/fast_reject.rs (renamed from src/librustc_middle/ty/fast_reject.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/flags.rs (renamed from src/librustc_middle/ty/flags.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/fold.rs (renamed from src/librustc_middle/ty/fold.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs (renamed from src/librustc_middle/ty/inhabitedness/def_id_forest.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/inhabitedness/mod.rs (renamed from src/librustc_middle/ty/inhabitedness/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs (renamed from src/librustc_middle/ty/instance.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs (renamed from src/librustc_middle/ty/layout.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/list.rs (renamed from src/librustc_middle/ty/list.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs (renamed from src/librustc_middle/ty/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/normalize_erasing_regions.rs (renamed from src/librustc_middle/ty/normalize_erasing_regions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/outlives.rs (renamed from src/librustc_middle/ty/outlives.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/mod.rs (renamed from src/librustc_middle/ty/print/mod.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs (renamed from src/librustc_middle/ty/print/pretty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/README.md (renamed from src/librustc_middle/ty/query/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/job.rs (renamed from src/librustc_middle/ty/query/job.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/keys.rs (renamed from src/librustc_middle/ty/query/keys.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/mod.rs (renamed from src/librustc_middle/ty/query/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/on_disk_cache.rs (renamed from src/librustc_middle/ty/query/on_disk_cache.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/plumbing.rs (renamed from src/librustc_middle/ty/query/plumbing.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/profiling_support.rs (renamed from src/librustc_middle/ty/query/profiling_support.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/stats.rs (renamed from src/librustc_middle/ty/query/stats.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/query/values.rs (renamed from src/librustc_middle/ty/query/values.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/relate.rs (renamed from src/librustc_middle/ty/relate.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/steal.rs (renamed from src/librustc_middle/ty/steal.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/structural_impls.rs (renamed from src/librustc_middle/ty/structural_impls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs (renamed from src/librustc_middle/ty/sty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/subst.rs (renamed from src/librustc_middle/ty/subst.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/trait_def.rs (renamed from src/librustc_middle/ty/trait_def.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs (renamed from src/librustc_middle/ty/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/walk.rs (renamed from src/librustc_middle/ty/walk.rs) | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/util/bug.rs (renamed from src/librustc_middle/util/bug.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/util/common.rs (renamed from src/librustc_middle/util/common.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/util/common/tests.rs (renamed from src/librustc_middle/util/common/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/Cargo.toml | 33 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/borrow_set.rs (renamed from src/librustc_mir/borrow_check/borrow_set.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/constraint_generation.rs (renamed from src/librustc_mir/borrow_check/constraint_generation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/constraints/graph.rs (renamed from src/librustc_mir/borrow_check/constraints/graph.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/constraints/mod.rs (renamed from src/librustc_mir/borrow_check/constraints/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/def_use.rs (renamed from src/librustc_mir/borrow_check/def_use.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs (renamed from src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/find_use.rs (renamed from src/librustc_mir/borrow_check/diagnostics/find_use.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs (renamed from src/librustc_mir/borrow_check/diagnostics/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/move_errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs (renamed from src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs (renamed from src/librustc_mir/borrow_check/diagnostics/region_errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs (renamed from src/librustc_mir/borrow_check/diagnostics/region_name.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/diagnostics/var_name.rs (renamed from src/librustc_mir/borrow_check/diagnostics/var_name.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/facts.rs (renamed from src/librustc_mir/borrow_check/facts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/invalidation.rs (renamed from src/librustc_mir/borrow_check/invalidation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/location.rs (renamed from src/librustc_mir/borrow_check/location.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/member_constraints.rs (renamed from src/librustc_mir/borrow_check/member_constraints.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/mod.rs (renamed from src/librustc_mir/borrow_check/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/nll.rs (renamed from src/librustc_mir/borrow_check/nll.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/path_utils.rs (renamed from src/librustc_mir/borrow_check/path_utils.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/place_ext.rs (renamed from src/librustc_mir/borrow_check/place_ext.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/places_conflict.rs (renamed from src/librustc_mir/borrow_check/places_conflict.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/prefixes.rs (renamed from src/librustc_mir/borrow_check/prefixes.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/region_infer/dump_mir.rs (renamed from src/librustc_mir/borrow_check/region_infer/dump_mir.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/region_infer/graphviz.rs (renamed from src/librustc_mir/borrow_check/region_infer/graphviz.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/region_infer/mod.rs (renamed from src/librustc_mir/borrow_check/region_infer/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs (renamed from src/librustc_mir/borrow_check/region_infer/opaque_types.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/region_infer/reverse_sccs.rs (renamed from src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/region_infer/values.rs (renamed from src/librustc_mir/borrow_check/region_infer/values.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/renumber.rs (renamed from src/librustc_mir/borrow_check/renumber.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs (renamed from src/librustc_mir/borrow_check/type_check/constraint_conversion.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs (renamed from src/librustc_mir/borrow_check/type_check/free_region_relations.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/input_output.rs (renamed from src/librustc_mir/borrow_check/type_check/input_output.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/liveness/mod.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/liveness/polonius.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/polonius.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs (renamed from src/librustc_mir/borrow_check/type_check/liveness/trace.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/mod.rs (renamed from src/librustc_mir/borrow_check/type_check/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs (renamed from src/librustc_mir/borrow_check/type_check/relate_tys.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/universal_regions.rs (renamed from src/librustc_mir/borrow_check/universal_regions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/used_muts.rs (renamed from src/librustc_mir/borrow_check/used_muts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/const_eval/error.rs (renamed from src/librustc_mir/const_eval/error.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/const_eval/eval_queries.rs (renamed from src/librustc_mir/const_eval/eval_queries.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/const_eval/fn_queries.rs (renamed from src/librustc_mir/const_eval/fn_queries.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/const_eval/machine.rs (renamed from src/librustc_mir/const_eval/machine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/const_eval/mod.rs (renamed from src/librustc_mir/const_eval/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/drop_flag_effects.rs (renamed from src/librustc_mir/dataflow/drop_flag_effects.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/cursor.rs (renamed from src/librustc_mir/dataflow/framework/cursor.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/direction.rs (renamed from src/librustc_mir/dataflow/framework/direction.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/engine.rs (renamed from src/librustc_mir/dataflow/framework/engine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/graphviz.rs (renamed from src/librustc_mir/dataflow/framework/graphviz.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/mod.rs (renamed from src/librustc_mir/dataflow/framework/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/tests.rs (renamed from src/librustc_mir/dataflow/framework/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/framework/visitor.rs (renamed from src/librustc_mir/dataflow/framework/visitor.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/borrowed_locals.rs (renamed from src/librustc_mir/dataflow/impls/borrowed_locals.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/borrows.rs (renamed from src/librustc_mir/dataflow/impls/borrows.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/init_locals.rs (renamed from src/librustc_mir/dataflow/impls/init_locals.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/liveness.rs (renamed from src/librustc_mir/dataflow/impls/liveness.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/mod.rs (renamed from src/librustc_mir/dataflow/impls/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/storage_liveness.rs (renamed from src/librustc_mir/dataflow/impls/storage_liveness.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/mod.rs (renamed from src/librustc_mir/dataflow/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/move_paths/abs_domain.rs (renamed from src/librustc_mir/dataflow/move_paths/abs_domain.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/move_paths/builder.rs (renamed from src/librustc_mir/dataflow/move_paths/builder.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/move_paths/mod.rs (renamed from src/librustc_mir/dataflow/move_paths/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/cast.rs (renamed from src/librustc_mir/interpret/cast.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/eval_context.rs (renamed from src/librustc_mir/interpret/eval_context.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/intern.rs (renamed from src/librustc_mir/interpret/intern.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/intrinsics.rs (renamed from src/librustc_mir/interpret/intrinsics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs (renamed from src/librustc_mir/interpret/intrinsics/caller_location.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/intrinsics/type_name.rs (renamed from src/librustc_mir/interpret/intrinsics/type_name.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/machine.rs (renamed from src/librustc_mir/interpret/machine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/memory.rs (renamed from src/librustc_mir/interpret/memory.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/mod.rs (renamed from src/librustc_mir/interpret/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/operand.rs (renamed from src/librustc_mir/interpret/operand.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/operator.rs (renamed from src/librustc_mir/interpret/operator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/place.rs (renamed from src/librustc_mir/interpret/place.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/step.rs (renamed from src/librustc_mir/interpret/step.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/terminator.rs (renamed from src/librustc_mir/interpret/terminator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/traits.rs (renamed from src/librustc_mir/interpret/traits.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/util.rs (renamed from src/librustc_mir/interpret/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/validity.rs (renamed from src/librustc_mir/interpret/validity.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/visitor.rs (renamed from src/librustc_mir/interpret/visitor.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/lib.rs (renamed from src/librustc_mir/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/collector.rs (renamed from src/librustc_mir/monomorphize/collector.rs) | 24 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/mod.rs (renamed from src/librustc_mir/monomorphize/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/partitioning/default.rs (renamed from src/librustc_mir/monomorphize/partitioning/default.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/partitioning/merging.rs (renamed from src/librustc_mir/monomorphize/partitioning/merging.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/partitioning/mod.rs (renamed from src/librustc_mir/monomorphize/partitioning/mod.rs) | 8 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/polymorphize.rs (renamed from src/librustc_mir/monomorphize/polymorphize.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/shim.rs (renamed from src/librustc_mir/shim.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/add_call_guards.rs (renamed from src/librustc_mir/transform/add_call_guards.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/add_moves_for_packed_drops.rs (renamed from src/librustc_mir/transform/add_moves_for_packed_drops.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/add_retag.rs (renamed from src/librustc_mir/transform/add_retag.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/mod.rs (renamed from src/librustc_mir/transform/check_consts/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/ops.rs (renamed from src/librustc_mir/transform/check_consts/ops.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs (renamed from src/librustc_mir/transform/check_consts/post_drop_elaboration.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/qualifs.rs (renamed from src/librustc_mir/transform/check_consts/qualifs.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/resolver.rs (renamed from src/librustc_mir/transform/check_consts/resolver.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs (renamed from src/librustc_mir/transform/check_consts/validation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_packed_ref.rs (renamed from src/librustc_mir/transform/check_packed_ref.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_unsafety.rs (renamed from src/librustc_mir/transform/check_unsafety.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs (renamed from src/librustc_mir/transform/cleanup_post_borrowck.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/const_prop.rs (renamed from src/librustc_mir/transform/const_prop.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/copy_prop.rs (renamed from src/librustc_mir/transform/copy_prop.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/deaggregator.rs (renamed from src/librustc_mir/transform/deaggregator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/dump_mir.rs (renamed from src/librustc_mir/transform/dump_mir.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/elaborate_drops.rs (renamed from src/librustc_mir/transform/elaborate_drops.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/generator.rs (renamed from src/librustc_mir/transform/generator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/inline.rs (renamed from src/librustc_mir/transform/inline.rs) | 10 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/instcombine.rs (renamed from src/librustc_mir/transform/instcombine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/instrument_coverage.rs (renamed from src/librustc_mir/transform/instrument_coverage.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/match_branches.rs (renamed from src/librustc_mir/transform/match_branches.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/mod.rs (renamed from src/librustc_mir/transform/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/no_landing_pads.rs (renamed from src/librustc_mir/transform/no_landing_pads.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/nrvo.rs (renamed from src/librustc_mir/transform/nrvo.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/promote_consts.rs (renamed from src/librustc_mir/transform/promote_consts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/qualify_min_const_fn.rs (renamed from src/librustc_mir/transform/qualify_min_const_fn.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs (renamed from src/librustc_mir/transform/remove_noop_landing_pads.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/required_consts.rs (renamed from src/librustc_mir/transform/required_consts.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/rustc_peek.rs (renamed from src/librustc_mir/transform/rustc_peek.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/simplify.rs (renamed from src/librustc_mir/transform/simplify.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/simplify_branches.rs (renamed from src/librustc_mir/transform/simplify_branches.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/simplify_comparison_integral.rs (renamed from src/librustc_mir/transform/simplify_comparison_integral.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/simplify_try.rs (renamed from src/librustc_mir/transform/simplify_try.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs (renamed from src/librustc_mir/transform/uninhabited_enum_branching.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/unreachable_prop.rs (renamed from src/librustc_mir/transform/unreachable_prop.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/validate.rs (renamed from src/librustc_mir/transform/validate.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/aggregate.rs (renamed from src/librustc_mir/util/aggregate.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/alignment.rs (renamed from src/librustc_mir/util/alignment.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/borrowck_errors.rs (renamed from src/librustc_mir/util/borrowck_errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/collect_writes.rs (renamed from src/librustc_mir/util/collect_writes.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/def_use.rs (renamed from src/librustc_mir/util/def_use.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/elaborate_drops.rs (renamed from src/librustc_mir/util/elaborate_drops.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/graphviz.rs (renamed from src/librustc_mir/util/graphviz.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/mod.rs (renamed from src/librustc_mir/util/mod.rs) | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/patch.rs (renamed from src/librustc_mir/util/patch.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/pretty.rs (renamed from src/librustc_mir/util/pretty.rs) | 11 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/spanview.rs | 461 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/util/storage.rs (renamed from src/librustc_mir/util/storage.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/Cargo.toml | 27 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/block.rs (renamed from src/librustc_mir_build/build/block.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/cfg.rs (renamed from src/librustc_mir_build/build/cfg.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_constant.rs (renamed from src/librustc_mir_build/build/expr/as_constant.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_operand.rs (renamed from src/librustc_mir_build/build/expr/as_operand.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_place.rs (renamed from src/librustc_mir_build/build/expr/as_place.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_rvalue.rs (renamed from src/librustc_mir_build/build/expr/as_rvalue.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_temp.rs (renamed from src/librustc_mir_build/build/expr/as_temp.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/category.rs (renamed from src/librustc_mir_build/build/expr/category.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/into.rs (renamed from src/librustc_mir_build/build/expr/into.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/mod.rs (renamed from src/librustc_mir_build/build/expr/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/expr/stmt.rs (renamed from src/librustc_mir_build/build/expr/stmt.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/into.rs (renamed from src/librustc_mir_build/build/into.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/mod.rs (renamed from src/librustc_mir_build/build/matches/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/simplify.rs (renamed from src/librustc_mir_build/build/matches/simplify.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/test.rs (renamed from src/librustc_mir_build/build/matches/test.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/util.rs (renamed from src/librustc_mir_build/build/matches/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/misc.rs (renamed from src/librustc_mir_build/build/misc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/mod.rs (renamed from src/librustc_mir_build/build/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/scope.rs (renamed from src/librustc_mir_build/build/scope.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/lib.rs (renamed from src/librustc_mir_build/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/lints.rs (renamed from src/librustc_mir_build/lints.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/constant.rs (renamed from src/librustc_mir_build/thir/constant.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/block.rs (renamed from src/librustc_mir_build/thir/cx/block.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/expr.rs (renamed from src/librustc_mir_build/thir/cx/expr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/mod.rs (renamed from src/librustc_mir_build/thir/cx/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/cx/to_ref.rs (renamed from src/librustc_mir_build/thir/cx/to_ref.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/mod.rs (renamed from src/librustc_mir_build/thir/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/_match.rs (renamed from src/librustc_mir_build/thir/pattern/_match.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs (renamed from src/librustc_mir_build/thir/pattern/check_match.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs (renamed from src/librustc_mir_build/thir/pattern/const_to_pat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/mod.rs (renamed from src/librustc_mir_build/thir/pattern/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/util.rs (renamed from src/librustc_mir_build/thir/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/Cargo.toml | 22 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/mod.rs (renamed from src/librustc_parse/lexer/mod.rs) | 121 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/tokentrees.rs (renamed from src/librustc_parse/lexer/tokentrees.rs) | 36 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/unescape_error_reporting.rs (renamed from src/librustc_parse/lexer/unescape_error_reporting.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/unicode_chars.rs (renamed from src/librustc_parse/lexer/unicode_chars.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lib.rs (renamed from src/librustc_parse/lib.rs) | 7 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/attr.rs (renamed from src/librustc_parse/parser/attr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs (renamed from src/librustc_parse/parser/diagnostics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs (renamed from src/librustc_parse/parser/expr.rs) | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/generics.rs (renamed from src/librustc_parse/parser/generics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs (renamed from src/librustc_parse/parser/item.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs (renamed from src/librustc_parse/parser/mod.rs) | 7 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/nonterminal.rs (renamed from src/librustc_parse/parser/nonterminal.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs (renamed from src/librustc_parse/parser/pat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs (renamed from src/librustc_parse/parser/path.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/stmt.rs (renamed from src/librustc_parse/parser/stmt.rs) | 7 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs (renamed from src/librustc_parse/parser/ty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/validate_attr.rs (renamed from src/librustc_parse/validate_attr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse_format/Cargo.toml | 9 | ||||
| -rw-r--r-- | compiler/rustc_parse_format/src/lib.rs (renamed from src/librustc_parse_format/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_parse_format/src/tests.rs (renamed from src/librustc_parse_format/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/Cargo.toml | 19 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs (renamed from src/librustc_passes/check_attr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_const.rs (renamed from src/librustc_passes/check_const.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs (renamed from src/librustc_passes/dead.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/diagnostic_items.rs (renamed from src/librustc_passes/diagnostic_items.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/entry.rs (renamed from src/librustc_passes/entry.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/hir_id_validator.rs (renamed from src/librustc_passes/hir_id_validator.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/hir_stats.rs (renamed from src/librustc_passes/hir_stats.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/intrinsicck.rs (renamed from src/librustc_passes/intrinsicck.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/lang_items.rs (renamed from src/librustc_passes/lang_items.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/layout_test.rs (renamed from src/librustc_passes/layout_test.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/lib.rs (renamed from src/librustc_passes/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/lib_features.rs (renamed from src/librustc_passes/lib_features.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/liveness.rs (renamed from src/librustc_passes/liveness.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/loops.rs (renamed from src/librustc_passes/loops.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/reachable.rs (renamed from src/librustc_passes/reachable.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/region.rs (renamed from src/librustc_passes/region.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/stability.rs (renamed from src/librustc_passes/stability.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/upvars.rs (renamed from src/librustc_passes/upvars.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/weak_lang_items.rs (renamed from src/librustc_passes/weak_lang_items.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_plugin_impl/Cargo.toml | 19 | ||||
| -rw-r--r-- | compiler/rustc_plugin_impl/src/build.rs (renamed from src/librustc_plugin_impl/build.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_plugin_impl/src/lib.rs (renamed from src/librustc_plugin_impl/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_plugin_impl/src/load.rs (renamed from src/librustc_plugin_impl/load.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_privacy/Cargo.toml | 16 | ||||
| -rw-r--r-- | compiler/rustc_privacy/src/lib.rs (renamed from src/librustc_privacy/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/Cargo.toml | 21 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/cache.rs (renamed from src/librustc_query_system/cache.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/README.md (renamed from src/librustc_query_system/dep_graph/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/debug.rs (renamed from src/librustc_query_system/dep_graph/debug.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/dep_node.rs (renamed from src/librustc_query_system/dep_graph/dep_node.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/graph.rs (renamed from src/librustc_query_system/dep_graph/graph.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/mod.rs (renamed from src/librustc_query_system/dep_graph/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/prev.rs (renamed from src/librustc_query_system/dep_graph/prev.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/query.rs (renamed from src/librustc_query_system/dep_graph/query.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/serialized.rs (renamed from src/librustc_query_system/dep_graph/serialized.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/lib.rs (renamed from src/librustc_query_system/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/query/README.md (renamed from src/librustc_query_system/query/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/query/caches.rs (renamed from src/librustc_query_system/query/caches.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/query/config.rs (renamed from src/librustc_query_system/query/config.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/query/job.rs (renamed from src/librustc_query_system/query/job.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/query/mod.rs (renamed from src/librustc_query_system/query/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_query_system/src/query/plumbing.rs (renamed from src/librustc_query_system/query/plumbing.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/Cargo.toml | 29 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/build_reduced_graph.rs (renamed from src/librustc_resolve/build_reduced_graph.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/check_unused.rs (renamed from src/librustc_resolve/check_unused.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/def_collector.rs (renamed from src/librustc_resolve/def_collector.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs (renamed from src/librustc_resolve/diagnostics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/imports.rs (renamed from src/librustc_resolve/imports.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs (renamed from src/librustc_resolve/late.rs) | 7 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs (renamed from src/librustc_resolve/late/diagnostics.rs) | 13 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs (renamed from src/librustc_resolve/late/lifetimes.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs (renamed from src/librustc_resolve/lib.rs) | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs (renamed from src/librustc_resolve/macros.rs) | 22 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/Cargo.toml | 20 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/src/dump_visitor.rs (renamed from src/librustc_save_analysis/dump_visitor.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/src/dumper.rs (renamed from src/librustc_save_analysis/dumper.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/src/lib.rs (renamed from src/librustc_save_analysis/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/src/sig.rs (renamed from src/librustc_save_analysis/sig.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_save_analysis/src/span_utils.rs (renamed from src/librustc_save_analysis/span_utils.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/Cargo.toml (renamed from src/librustc_serialize/Cargo.toml) | 6 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/collection_impls.rs (renamed from src/librustc_serialize/collection_impls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/json.rs (renamed from src/librustc_serialize/json.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/json/tests.rs (renamed from src/librustc_serialize/json/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/leb128.rs (renamed from src/librustc_serialize/leb128.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/lib.rs (renamed from src/librustc_serialize/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/opaque.rs (renamed from src/librustc_serialize/opaque.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/serialize.rs (renamed from src/librustc_serialize/serialize.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/tests/json.rs (renamed from src/librustc_serialize/tests/json.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/tests/leb128.rs (renamed from src/librustc_serialize/tests/leb128.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_serialize/tests/opaque.rs (renamed from src/librustc_serialize/tests/opaque.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/Cargo.toml | 20 | ||||
| -rw-r--r-- | compiler/rustc_session/src/cgu_reuse_tracker.rs (renamed from src/librustc_session/cgu_reuse_tracker.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/code_stats.rs (renamed from src/librustc_session/code_stats.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config.rs (renamed from src/librustc_session/config.rs) | 32 | ||||
| -rw-r--r-- | compiler/rustc_session/src/filesearch.rs (renamed from src/librustc_session/filesearch.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/lib.rs (renamed from src/librustc_session/lib.rs) | 1 | ||||
| -rw-r--r-- | compiler/rustc_session/src/lint.rs (renamed from src/librustc_session/lint.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/lint/builtin.rs (renamed from src/librustc_session/lint/builtin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs (renamed from src/librustc_session/options.rs) | 50 | ||||
| -rw-r--r-- | compiler/rustc_session/src/output.rs (renamed from src/librustc_session/output.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/parse.rs (renamed from src/librustc_session/parse.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/search_paths.rs (renamed from src/librustc_session/search_paths.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_session/src/session.rs (renamed from src/librustc_session/session.rs) | 52 | ||||
| -rw-r--r-- | compiler/rustc_session/src/utils.rs (renamed from src/librustc_session/utils.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/Cargo.toml | 21 | ||||
| -rw-r--r-- | compiler/rustc_span/src/analyze_source_file.rs (renamed from src/librustc_span/analyze_source_file.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/analyze_source_file/tests.rs (renamed from src/librustc_span/analyze_source_file/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/caching_source_map_view.rs (renamed from src/librustc_span/caching_source_map_view.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/def_id.rs (renamed from src/librustc_span/def_id.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/edition.rs (renamed from src/librustc_span/edition.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/fatal_error.rs (renamed from src/librustc_span/fatal_error.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/hygiene.rs (renamed from src/librustc_span/hygiene.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/lib.rs (renamed from src/librustc_span/lib.rs) | 7 | ||||
| -rw-r--r-- | compiler/rustc_span/src/source_map.rs (renamed from src/librustc_span/source_map.rs) | 9 | ||||
| -rw-r--r-- | compiler/rustc_span/src/source_map/tests.rs (renamed from src/librustc_span/source_map/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/span_encoding.rs (renamed from src/librustc_span/span_encoding.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs (renamed from src/librustc_span/symbol.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol/tests.rs (renamed from src/librustc_span/symbol/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_span/src/tests.rs (renamed from src/librustc_span/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/Cargo.toml | 21 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/legacy.rs (renamed from src/librustc_symbol_mangling/legacy.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/lib.rs (renamed from src/librustc_symbol_mangling/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/test.rs (renamed from src/librustc_symbol_mangling/test.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_symbol_mangling/src/v0.rs (renamed from src/librustc_symbol_mangling/v0.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/Cargo.toml | 14 | ||||
| -rw-r--r-- | compiler/rustc_target/README.md (renamed from src/librustc_target/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/aarch64.rs (renamed from src/librustc_target/abi/call/aarch64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/amdgpu.rs (renamed from src/librustc_target/abi/call/amdgpu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/arm.rs (renamed from src/librustc_target/abi/call/arm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/avr.rs (renamed from src/librustc_target/abi/call/avr.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/hexagon.rs (renamed from src/librustc_target/abi/call/hexagon.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mips.rs (renamed from src/librustc_target/abi/call/mips.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mips64.rs (renamed from src/librustc_target/abi/call/mips64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs (renamed from src/librustc_target/abi/call/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/msp430.rs (renamed from src/librustc_target/abi/call/msp430.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/nvptx.rs (renamed from src/librustc_target/abi/call/nvptx.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/nvptx64.rs (renamed from src/librustc_target/abi/call/nvptx64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/powerpc.rs (renamed from src/librustc_target/abi/call/powerpc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/powerpc64.rs (renamed from src/librustc_target/abi/call/powerpc64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/riscv.rs (renamed from src/librustc_target/abi/call/riscv.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/s390x.rs (renamed from src/librustc_target/abi/call/s390x.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/sparc.rs (renamed from src/librustc_target/abi/call/sparc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/sparc64.rs (renamed from src/librustc_target/abi/call/sparc64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/wasm32.rs (renamed from src/librustc_target/abi/call/wasm32.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs (renamed from src/librustc_target/abi/call/wasm32_bindgen_compat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/x86.rs (renamed from src/librustc_target/abi/call/x86.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/x86_64.rs (renamed from src/librustc_target/abi/call/x86_64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/x86_win64.rs (renamed from src/librustc_target/abi/call/x86_win64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs (renamed from src/librustc_target/abi/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/aarch64.rs (renamed from src/librustc_target/asm/aarch64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/arm.rs (renamed from src/librustc_target/asm/arm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/hexagon.rs (renamed from src/librustc_target/asm/hexagon.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/mod.rs (renamed from src/librustc_target/asm/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/nvptx.rs (renamed from src/librustc_target/asm/nvptx.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/riscv.rs (renamed from src/librustc_target/asm/riscv.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/x86.rs (renamed from src/librustc_target/asm/x86.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/lib.rs (renamed from src/librustc_target/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_apple_darwin.rs (renamed from src/librustc_target/spec/aarch64_apple_darwin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_apple_ios.rs (renamed from src/librustc_target/spec/aarch64_apple_ios.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_apple_tvos.rs (renamed from src/librustc_target/spec/aarch64_apple_tvos.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_fuchsia.rs (renamed from src/librustc_target/spec/aarch64_fuchsia.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_linux_android.rs (renamed from src/librustc_target/spec/aarch64_linux_android.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs (renamed from src/librustc_target/spec/aarch64_pc_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs (renamed from src/librustc_target/spec/aarch64_unknown_cloudabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs (renamed from src/librustc_target/spec/aarch64_unknown_freebsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs (renamed from src/librustc_target/spec/aarch64_unknown_hermit.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/aarch64_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs (renamed from src/librustc_target/spec/aarch64_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs (renamed from src/librustc_target/spec/aarch64_unknown_netbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_none.rs (renamed from src/librustc_target/spec/aarch64_unknown_none.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs (renamed from src/librustc_target/spec/aarch64_unknown_none_softfloat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs (renamed from src/librustc_target/spec/aarch64_unknown_openbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_unknown_redox.rs (renamed from src/librustc_target/spec/aarch64_unknown_redox.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/aarch64_uwp_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs (renamed from src/librustc_target/spec/aarch64_wrs_vxworks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/abi.rs (renamed from src/librustc_target/spec/abi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/abi/tests.rs (renamed from src/librustc_target/spec/abi/tests.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/android_base.rs (renamed from src/librustc_target/spec/android_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/apple_base.rs (renamed from src/librustc_target/spec/apple_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/apple_sdk_base.rs (renamed from src/librustc_target/spec/apple_sdk_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/arm_base.rs (renamed from src/librustc_target/spec/arm_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/arm_linux_androideabi.rs (renamed from src/librustc_target/spec/arm_linux_androideabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/arm_unknown_linux_gnueabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs (renamed from src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs (renamed from src/librustc_target/spec/arm_unknown_linux_musleabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs (renamed from src/librustc_target/spec/arm_unknown_linux_musleabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armebv7r_none_eabi.rs (renamed from src/librustc_target/spec/armebv7r_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs (renamed from src/librustc_target/spec/armebv7r_none_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs (renamed from src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs (renamed from src/librustc_target/spec/armv6_unknown_freebsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs (renamed from src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_apple_ios.rs (renamed from src/librustc_target/spec/armv7_apple_ios.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_linux_androideabi.rs (renamed from src/librustc_target/spec/armv7_linux_androideabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs (renamed from src/librustc_target/spec/armv7_unknown_freebsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_musleabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs (renamed from src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs (renamed from src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7a_none_eabi.rs (renamed from src/librustc_target/spec/armv7a_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7a_none_eabihf.rs (renamed from src/librustc_target/spec/armv7a_none_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7r_none_eabi.rs (renamed from src/librustc_target/spec/armv7r_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7r_none_eabihf.rs (renamed from src/librustc_target/spec/armv7r_none_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/armv7s_apple_ios.rs (renamed from src/librustc_target/spec/armv7s_apple_ios.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs (renamed from src/librustc_target/spec/asmjs_unknown_emscripten.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/avr_gnu_base.rs (renamed from src/librustc_target/spec/avr_gnu_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs (renamed from src/librustc_target/spec/avr_unknown_gnu_atmega328.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/cloudabi_base.rs (renamed from src/librustc_target/spec/cloudabi_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/crt_objects.rs (renamed from src/librustc_target/spec/crt_objects.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/dragonfly_base.rs (renamed from src/librustc_target/spec/dragonfly_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/freebsd_base.rs (renamed from src/librustc_target/spec/freebsd_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/fuchsia_base.rs (renamed from src/librustc_target/spec/fuchsia_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/haiku_base.rs (renamed from src/librustc_target/spec/haiku_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/hermit_base.rs (renamed from src/librustc_target/spec/hermit_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/hermit_kernel_base.rs (renamed from src/librustc_target/spec/hermit_kernel_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs (renamed from src/librustc_target/spec/hexagon_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i386_apple_ios.rs (renamed from src/librustc_target/spec/i386_apple_ios.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i586_pc_windows_msvc.rs (renamed from src/librustc_target/spec/i586_pc_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i586_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/i586_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i586_unknown_linux_musl.rs (renamed from src/librustc_target/spec/i586_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_apple_darwin.rs (renamed from src/librustc_target/spec/i686_apple_darwin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_linux_android.rs (renamed from src/librustc_target/spec/i686_linux_android.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs (renamed from src/librustc_target/spec/i686_pc_windows_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs (renamed from src/librustc_target/spec/i686_pc_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs (renamed from src/librustc_target/spec/i686_unknown_cloudabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_freebsd.rs (renamed from src/librustc_target/spec/i686_unknown_freebsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_haiku.rs (renamed from src/librustc_target/spec/i686_unknown_haiku.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/i686_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs (renamed from src/librustc_target/spec/i686_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_netbsd.rs (renamed from src/librustc_target/spec/i686_unknown_netbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_openbsd.rs (renamed from src/librustc_target/spec/i686_unknown_openbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_unknown_uefi.rs (renamed from src/librustc_target/spec/i686_unknown_uefi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs (renamed from src/librustc_target/spec/i686_uwp_windows_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/i686_uwp_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/i686_wrs_vxworks.rs (renamed from src/librustc_target/spec/i686_wrs_vxworks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/illumos_base.rs (renamed from src/librustc_target/spec/illumos_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/l4re_base.rs (renamed from src/librustc_target/spec/l4re_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/linux_base.rs (renamed from src/librustc_target/spec/linux_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/linux_kernel_base.rs (renamed from src/librustc_target/spec/linux_kernel_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/linux_musl_base.rs (renamed from src/librustc_target/spec/linux_musl_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs (renamed from src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs (renamed from src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mips_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs (renamed from src/librustc_target/spec/mips_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs (renamed from src/librustc_target/spec/mips_unknown_linux_uclibc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsel_sony_psp.rs (renamed from src/librustc_target/spec/mipsel_sony_psp.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsel_sony_psp_linker_script.ld (renamed from src/librustc_target/spec/mipsel_sony_psp_linker_script.ld) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mipsel_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs (renamed from src/librustc_target/spec/mipsel_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs (renamed from src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs (renamed from src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mod.rs (renamed from src/librustc_target/spec/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/msp430_none_elf.rs (renamed from src/librustc_target/spec/msp430_none_elf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/msvc_base.rs (renamed from src/librustc_target/spec/msvc_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/netbsd_base.rs (renamed from src/librustc_target/spec/netbsd_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs (renamed from src/librustc_target/spec/nvptx64_nvidia_cuda.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/openbsd_base.rs (renamed from src/librustc_target/spec/openbsd_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs (renamed from src/librustc_target/spec/powerpc64_unknown_freebsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs (renamed from src/librustc_target/spec/powerpc64_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs (renamed from src/librustc_target/spec/powerpc64_wrs_vxworks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs (renamed from src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/powerpc_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs (renamed from src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs (renamed from src/librustc_target/spec/powerpc_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs (renamed from src/librustc_target/spec/powerpc_unknown_netbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs (renamed from src/librustc_target/spec/powerpc_wrs_vxworks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs (renamed from src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/redox_base.rs (renamed from src/librustc_target/spec/redox_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv32i_unknown_none_elf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv32imac_unknown_none_elf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv32imc_unknown_none_elf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv64gc_unknown_none_elf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs (renamed from src/librustc_target/spec/riscv64imac_unknown_none_elf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/riscv_base.rs (renamed from src/librustc_target/spec/riscv_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/s390x_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/solaris_base.rs (renamed from src/librustc_target/spec/solaris_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/sparc64_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs (renamed from src/librustc_target/spec/sparc64_unknown_netbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs (renamed from src/librustc_target/spec/sparc64_unknown_openbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/sparc_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs (renamed from src/librustc_target/spec/sparcv9_sun_solaris.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/tests/tests_impl.rs (renamed from src/librustc_target/spec/tests/tests_impl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumb_base.rs (renamed from src/librustc_target/spec/thumb_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs (renamed from src/librustc_target/spec/thumbv4t_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs (renamed from src/librustc_target/spec/thumbv6m_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs (renamed from src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs (renamed from src/librustc_target/spec/thumbv7em_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs (renamed from src/librustc_target/spec/thumbv7em_none_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs (renamed from src/librustc_target/spec/thumbv7m_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs (renamed from src/librustc_target/spec/thumbv7neon_linux_androideabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs (renamed from src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs (renamed from src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs (renamed from src/librustc_target/spec/thumbv8m_base_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs (renamed from src/librustc_target/spec/thumbv8m_main_none_eabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs (renamed from src/librustc_target/spec/thumbv8m_main_none_eabihf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/uefi_msvc_base.rs (renamed from src/librustc_target/spec/uefi_msvc_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/vxworks_base.rs (renamed from src/librustc_target/spec/vxworks_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/wasm32_base.rs (renamed from src/librustc_target/spec/wasm32_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs (renamed from src/librustc_target/spec/wasm32_unknown_emscripten.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs (renamed from src/librustc_target/spec/wasm32_unknown_unknown.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/wasm32_wasi.rs (renamed from src/librustc_target/spec/wasm32_wasi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/windows_gnu_base.rs (renamed from src/librustc_target/spec/windows_gnu_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/windows_msvc_base.rs (renamed from src/librustc_target/spec/windows_msvc_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs (renamed from src/librustc_target/spec/windows_uwp_gnu_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs (renamed from src/librustc_target/spec/windows_uwp_msvc_base.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_apple_darwin.rs (renamed from src/librustc_target/spec/x86_64_apple_darwin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_apple_ios.rs (renamed from src/librustc_target/spec/x86_64_apple_ios.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs (renamed from src/librustc_target/spec/x86_64_apple_ios_macabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_apple_tvos.rs (renamed from src/librustc_target/spec/x86_64_apple_tvos.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs (renamed from src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_fuchsia.rs (renamed from src/librustc_target/spec/x86_64_fuchsia.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_linux_android.rs (renamed from src/librustc_target/spec/x86_64_linux_android.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_linux_kernel.rs (renamed from src/librustc_target/spec/x86_64_linux_kernel.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs (renamed from src/librustc_target/spec/x86_64_pc_windows_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs (renamed from src/librustc_target/spec/x86_64_pc_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs (renamed from src/librustc_target/spec/x86_64_rumprun_netbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_sun_solaris.rs (renamed from src/librustc_target/spec/x86_64_sun_solaris.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs (renamed from src/librustc_target/spec/x86_64_unknown_cloudabi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs (renamed from src/librustc_target/spec/x86_64_unknown_dragonfly.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs (renamed from src/librustc_target/spec/x86_64_unknown_freebsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs (renamed from src/librustc_target/spec/x86_64_unknown_haiku.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs (renamed from src/librustc_target/spec/x86_64_unknown_hermit.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs (renamed from src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs (renamed from src/librustc_target/spec/x86_64_unknown_illumos.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs (renamed from src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs (renamed from src/librustc_target/spec/x86_64_unknown_linux_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs (renamed from src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs (renamed from src/librustc_target/spec/x86_64_unknown_linux_musl.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs (renamed from src/librustc_target/spec/x86_64_unknown_netbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs (renamed from src/librustc_target/spec/x86_64_unknown_openbsd.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_redox.rs (renamed from src/librustc_target/spec/x86_64_unknown_redox.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs (renamed from src/librustc_target/spec/x86_64_unknown_uefi.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs (renamed from src/librustc_target/spec/x86_64_uwp_windows_gnu.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs (renamed from src/librustc_target/spec/x86_64_uwp_windows_msvc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs (renamed from src/librustc_target/spec/x86_64_wrs_vxworks.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/Cargo.toml | 25 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/autoderef.rs (renamed from src/librustc_trait_selection/autoderef.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/infer.rs (renamed from src/librustc_trait_selection/infer.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/lib.rs (renamed from src/librustc_trait_selection/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/opaque_types.rs (renamed from src/librustc_trait_selection/opaque_types.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/auto_trait.rs (renamed from src/librustc_trait_selection/traits/auto_trait.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs (renamed from src/librustc_trait_selection/traits/chalk_fulfill.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/codegen/mod.rs (renamed from src/librustc_trait_selection/traits/codegen/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs (renamed from src/librustc_trait_selection/traits/coherence.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/engine.rs (renamed from src/librustc_trait_selection/traits/engine.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs (renamed from src/librustc_trait_selection/traits/error_reporting/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs (renamed from src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs (renamed from src/librustc_trait_selection/traits/error_reporting/suggestions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/fulfill.rs (renamed from src/librustc_trait_selection/traits/fulfill.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/misc.rs (renamed from src/librustc_trait_selection/traits/misc.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs (renamed from src/librustc_trait_selection/traits/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/object_safety.rs (renamed from src/librustc_trait_selection/traits/object_safety.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/on_unimplemented.rs (renamed from src/librustc_trait_selection/traits/on_unimplemented.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs (renamed from src/librustc_trait_selection/traits/project.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs (renamed from src/librustc_trait_selection/traits/query/dropck_outlives.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs (renamed from src/librustc_trait_selection/traits/query/evaluate_obligation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/method_autoderef.rs (renamed from src/librustc_trait_selection/traits/query/method_autoderef.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/mod.rs (renamed from src/librustc_trait_selection/traits/query/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/normalize.rs (renamed from src/librustc_trait_selection/traits/query/normalize.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs (renamed from src/librustc_trait_selection/traits/query/outlives_bounds.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs (renamed from src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs (renamed from src/librustc_trait_selection/traits/query/type_op/custom.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs (renamed from src/librustc_trait_selection/traits/query/type_op/eq.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs (renamed from src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs (renamed from src/librustc_trait_selection/traits/query/type_op/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs (renamed from src/librustc_trait_selection/traits/query/type_op/normalize.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs (renamed from src/librustc_trait_selection/traits/query/type_op/outlives.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs (renamed from src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs (renamed from src/librustc_trait_selection/traits/query/type_op/subtype.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs (renamed from src/librustc_trait_selection/traits/select/candidate_assembly.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/confirmation.rs (renamed from src/librustc_trait_selection/traits/select/confirmation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs (renamed from src/librustc_trait_selection/traits/select/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/specialize/mod.rs (renamed from src/librustc_trait_selection/traits/specialize/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs (renamed from src/librustc_trait_selection/traits/specialize/specialization_graph.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/structural_match.rs (renamed from src/librustc_trait_selection/traits/structural_match.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/util.rs (renamed from src/librustc_trait_selection/traits/util.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs (renamed from src/librustc_trait_selection/traits/wf.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/Cargo.toml | 19 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/chalk/db.rs (renamed from src/librustc_traits/chalk/db.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/chalk/lowering.rs (renamed from src/librustc_traits/chalk/lowering.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/chalk/mod.rs (renamed from src/librustc_traits/chalk/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/dropck_outlives.rs (renamed from src/librustc_traits/dropck_outlives.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/evaluate_obligation.rs (renamed from src/librustc_traits/evaluate_obligation.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/implied_outlives_bounds.rs (renamed from src/librustc_traits/implied_outlives_bounds.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/lib.rs (renamed from src/librustc_traits/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/normalize_erasing_regions.rs (renamed from src/librustc_traits/normalize_erasing_regions.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/normalize_projection_ty.rs (renamed from src/librustc_traits/normalize_projection_ty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/type_op.rs (renamed from src/librustc_traits/type_op.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ty/Cargo.toml | 17 | ||||
| -rw-r--r-- | compiler/rustc_ty/src/common_traits.rs (renamed from src/librustc_ty/common_traits.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ty/src/instance.rs (renamed from src/librustc_ty/instance.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ty/src/lib.rs (renamed from src/librustc_ty/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ty/src/needs_drop.rs (renamed from src/librustc_ty/needs_drop.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_ty/src/ty.rs (renamed from src/librustc_ty/ty.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/Cargo.toml | 27 | ||||
| -rw-r--r-- | compiler/rustc_typeck/README.md (renamed from src/librustc_typeck/README.md) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/errors.rs (renamed from src/librustc_typeck/astconv/errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/generics.rs (renamed from src/librustc_typeck/astconv/generics.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/mod.rs (renamed from src/librustc_typeck/astconv/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/bounds.rs (renamed from src/librustc_typeck/bounds.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/_match.rs (renamed from src/librustc_typeck/check/_match.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/autoderef.rs (renamed from src/librustc_typeck/check/autoderef.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/callee.rs (renamed from src/librustc_typeck/check/callee.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/cast.rs (renamed from src/librustc_typeck/check/cast.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/closure.rs (renamed from src/librustc_typeck/check/closure.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/coercion.rs (renamed from src/librustc_typeck/check/coercion.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/compare_method.rs (renamed from src/librustc_typeck/check/compare_method.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/demand.rs (renamed from src/librustc_typeck/check/demand.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/dropck.rs (renamed from src/librustc_typeck/check/dropck.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/expr.rs (renamed from src/librustc_typeck/check/expr.rs) | 55 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/generator_interior.rs (renamed from src/librustc_typeck/check/generator_interior.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/intrinsic.rs (renamed from src/librustc_typeck/check/intrinsic.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/confirm.rs (renamed from src/librustc_typeck/check/method/confirm.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/mod.rs (renamed from src/librustc_typeck/check/method/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/probe.rs (renamed from src/librustc_typeck/check/method/probe.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/suggest.rs (renamed from src/librustc_typeck/check/method/suggest.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/mod.rs (renamed from src/librustc_typeck/check/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/op.rs (renamed from src/librustc_typeck/check/op.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/pat.rs (renamed from src/librustc_typeck/check/pat.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/place_op.rs (renamed from src/librustc_typeck/check/place_op.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/regionck.rs (renamed from src/librustc_typeck/check/regionck.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/upvar.rs (renamed from src/librustc_typeck/check/upvar.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/wfcheck.rs (renamed from src/librustc_typeck/check/wfcheck.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/writeback.rs (renamed from src/librustc_typeck/check/writeback.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check_unused.rs (renamed from src/librustc_typeck/check_unused.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/builtin.rs (renamed from src/librustc_typeck/coherence/builtin.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/inherent_impls.rs (renamed from src/librustc_typeck/coherence/inherent_impls.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs (renamed from src/librustc_typeck/coherence/inherent_impls_overlap.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/mod.rs (renamed from src/librustc_typeck/coherence/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/orphan.rs (renamed from src/librustc_typeck/coherence/orphan.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/unsafety.rs (renamed from src/librustc_typeck/coherence/unsafety.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect.rs (renamed from src/librustc_typeck/collect.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect/type_of.rs (renamed from src/librustc_typeck/collect/type_of.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/constrained_generic_params.rs (renamed from src/librustc_typeck/constrained_generic_params.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/expr_use_visitor.rs (renamed from src/librustc_typeck/expr_use_visitor.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/impl_wf_check.rs (renamed from src/librustc_typeck/impl_wf_check.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs (renamed from src/librustc_typeck/impl_wf_check/min_specialization.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/lib.rs (renamed from src/librustc_typeck/lib.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/mem_categorization.rs (renamed from src/librustc_typeck/mem_categorization.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/outlives/explicit.rs (renamed from src/librustc_typeck/outlives/explicit.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/outlives/implicit_infer.rs (renamed from src/librustc_typeck/outlives/implicit_infer.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/outlives/mod.rs (renamed from src/librustc_typeck/outlives/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/outlives/test.rs (renamed from src/librustc_typeck/outlives/test.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/outlives/utils.rs (renamed from src/librustc_typeck/outlives/utils.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/structured_errors.rs (renamed from src/librustc_typeck/structured_errors.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/variance/constraints.rs (renamed from src/librustc_typeck/variance/constraints.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/variance/mod.rs (renamed from src/librustc_typeck/variance/mod.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/variance/solve.rs (renamed from src/librustc_typeck/variance/solve.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/variance/terms.rs (renamed from src/librustc_typeck/variance/terms.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/variance/test.rs (renamed from src/librustc_typeck/variance/test.rs) | 0 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/variance/xform.rs (renamed from src/librustc_typeck/variance/xform.rs) | 0 | ||||
| -rw-r--r-- | library/alloc/src/borrow.rs | 4 | ||||
| -rw-r--r-- | library/alloc/src/boxed.rs | 8 | ||||
| -rw-r--r-- | library/alloc/src/collections/vec_deque.rs | 17 | ||||
| -rw-r--r-- | library/alloc/src/rc.rs | 8 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 6 | ||||
| -rw-r--r-- | library/alloc/src/vec.rs | 22 | ||||
| -rw-r--r-- | library/core/benches/num/flt2dec/strategy/dragon.rs | 49 | ||||
| -rw-r--r-- | library/core/benches/num/flt2dec/strategy/grisu.rs | 49 | ||||
| -rw-r--r-- | library/core/src/array/mod.rs | 13 | ||||
| -rw-r--r-- | library/core/src/clone.rs | 13 | ||||
| -rw-r--r-- | library/core/src/convert/mod.rs | 52 | ||||
| -rw-r--r-- | library/core/src/fmt/float.rs | 116 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/mod.rs | 38 | ||||
| -rw-r--r-- | library/core/src/iter/mod.rs | 80 | ||||
| -rw-r--r-- | library/core/src/iter/traits/double_ended.rs | 7 | ||||
| -rw-r--r-- | library/core/src/iter/traits/iterator.rs | 124 | ||||
| -rw-r--r-- | library/core/src/macros/mod.rs | 2 | ||||
| -rw-r--r-- | library/core/src/marker.rs | 59 | ||||
| -rw-r--r-- | library/core/src/mem/maybe_uninit.rs | 38 | ||||
| -rw-r--r-- | library/core/src/num/flt2dec/mod.rs | 226 | ||||
| -rw-r--r-- | library/core/src/num/flt2dec/strategy/dragon.rs | 41 | ||||
| -rw-r--r-- | library/core/src/num/flt2dec/strategy/grisu.rs | 97 | ||||
| -rw-r--r-- | library/core/src/ops/control_flow.rs | 67 | ||||
| -rw-r--r-- | library/core/src/ops/mod.rs | 4 | ||||
| -rw-r--r-- | library/core/src/panic.rs | 9 | ||||
| -rw-r--r-- | library/core/src/pin.rs | 6 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 173 | ||||
| -rw-r--r-- | library/core/tests/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/tests/num/flt2dec/mod.rs | 71 | ||||
| -rw-r--r-- | library/core/tests/num/flt2dec/random.rs | 31 | ||||
| -rw-r--r-- | library/core/tests/option.rs | 1 | ||||
| -rw-r--r-- | library/core/tests/result.rs | 1 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/client.rs | 10 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/mod.rs | 3 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/server.rs | 34 | ||||
| -rw-r--r-- | library/std/src/ascii.rs | 2 | ||||
| -rw-r--r-- | library/std/src/backtrace.rs | 55 | ||||
| -rw-r--r-- | library/std/src/backtrace/tests.rs | 53 | ||||
| -rw-r--r-- | library/std/src/collections/hash/map.rs | 933 | ||||
| -rw-r--r-- | library/std/src/collections/hash/map/tests.rs | 926 | ||||
| -rw-r--r-- | library/std/src/collections/hash/set.rs | 422 | ||||
| -rw-r--r-- | library/std/src/collections/hash/set/tests.rs | 415 | ||||
| -rw-r--r-- | library/std/src/env.rs | 163 | ||||
| -rw-r--r-- | library/std/src/env/tests.rs | 102 | ||||
| -rw-r--r-- | library/std/src/error.rs | 44 | ||||
| -rw-r--r-- | library/std/src/error/tests.rs | 37 | ||||
| -rw-r--r-- | library/std/src/f32.rs | 766 | ||||
| -rw-r--r-- | library/std/src/f32/tests.rs | 759 | ||||
| -rw-r--r-- | library/std/src/f64.rs | 762 | ||||
| -rw-r--r-- | library/std/src/f64/tests.rs | 755 | ||||
| -rw-r--r-- | library/std/src/ffi/c_str.rs | 203 | ||||
| -rw-r--r-- | library/std/src/ffi/c_str/tests.rs | 195 | ||||
| -rw-r--r-- | library/std/src/ffi/os_str.rs | 172 | ||||
| -rw-r--r-- | library/std/src/ffi/os_str/tests.rs | 165 | ||||
| -rw-r--r-- | library/std/src/fs.rs | 1381 | ||||
| -rw-r--r-- | library/std/src/fs/tests.rs | 1339 | ||||
| -rw-r--r-- | library/std/src/io/buffered.rs | 923 | ||||
| -rw-r--r-- | library/std/src/io/buffered/tests.rs | 916 | ||||
| -rw-r--r-- | library/std/src/io/cursor.rs | 531 | ||||
| -rw-r--r-- | library/std/src/io/cursor/tests.rs | 516 | ||||
| -rw-r--r-- | library/std/src/io/error.rs | 60 | ||||
| -rw-r--r-- | library/std/src/io/error/tests.rs | 53 | ||||
| -rw-r--r-- | library/std/src/io/impls.rs | 64 | ||||
| -rw-r--r-- | library/std/src/io/impls/tests.rs | 57 | ||||
| -rw-r--r-- | library/std/src/io/mod.rs | 501 | ||||
| -rw-r--r-- | library/std/src/io/stdio.rs | 54 | ||||
| -rw-r--r-- | library/std/src/io/stdio/tests.rs | 47 | ||||
| -rw-r--r-- | library/std/src/io/tests.rs | 494 | ||||
| -rw-r--r-- | library/std/src/io/util.rs | 71 | ||||
| -rw-r--r-- | library/std/src/io/util/tests.rs | 45 | ||||
| -rw-r--r-- | library/std/src/keyword_docs.rs | 26 | ||||
| -rw-r--r-- | library/std/src/lazy.rs | 337 | ||||
| -rw-r--r-- | library/std/src/lazy/tests.rs | 323 | ||||
| -rw-r--r-- | library/std/src/lib.rs | 2 | ||||
| -rw-r--r-- | library/std/src/memchr.rs | 90 | ||||
| -rw-r--r-- | library/std/src/memchr/tests.rs | 86 | ||||
| -rw-r--r-- | library/std/src/net/addr.rs | 240 | ||||
| -rw-r--r-- | library/std/src/net/addr/tests.rs | 229 | ||||
| -rw-r--r-- | library/std/src/net/ip.rs | 1010 | ||||
| -rw-r--r-- | library/std/src/net/ip/tests.rs | 811 | ||||
| -rw-r--r-- | library/std/src/net/parser.rs | 146 | ||||
| -rw-r--r-- | library/std/src/net/parser/tests.rs | 139 | ||||
| -rw-r--r-- | library/std/src/net/tcp.rs | 870 | ||||
| -rw-r--r-- | library/std/src/net/tcp/tests.rs | 862 | ||||
| -rw-r--r-- | library/std/src/net/udp.rs | 380 | ||||
| -rw-r--r-- | library/std/src/net/udp/tests.rs | 372 | ||||
| -rw-r--r-- | library/std/src/num.rs | 253 | ||||
| -rw-r--r-- | library/std/src/num/benches.rs | 9 | ||||
| -rw-r--r-- | library/std/src/num/tests.rs | 230 | ||||
| -rw-r--r-- | library/std/src/os/raw/mod.rs | 25 | ||||
| -rw-r--r-- | library/std/src/os/raw/tests.rs | 16 | ||||
| -rw-r--r-- | library/std/src/path.rs | 1403 | ||||
| -rw-r--r-- | library/std/src/path/tests.rs | 1394 | ||||
| -rw-r--r-- | library/std/src/prelude/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/primitive_docs.rs | 49 | ||||
| -rw-r--r-- | library/std/src/process.rs | 411 | ||||
| -rw-r--r-- | library/std/src/process/tests.rs | 401 | ||||
| -rw-r--r-- | library/std/src/sync/barrier.rs | 42 | ||||
| -rw-r--r-- | library/std/src/sync/barrier/tests.rs | 35 | ||||
| -rw-r--r-- | library/std/src/sync/condvar.rs | 218 | ||||
| -rw-r--r-- | library/std/src/sync/condvar/tests.rs | 211 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/mod.rs | 1367 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/mpsc_queue.rs | 54 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/mpsc_queue/tests.rs | 47 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/spsc_queue.rs | 108 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/spsc_queue/tests.rs | 101 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/sync_tests.rs | 647 | ||||
| -rw-r--r-- | library/std/src/sync/mpsc/tests.rs | 706 | ||||
| -rw-r--r-- | library/std/src/sync/mutex.rs | 245 | ||||
| -rw-r--r-- | library/std/src/sync/mutex/tests.rs | 238 | ||||
| -rw-r--r-- | library/std/src/sync/once.rs | 123 | ||||
| -rw-r--r-- | library/std/src/sync/once/tests.rs | 116 | ||||
| -rw-r--r-- | library/std/src/sync/rwlock.rs | 254 | ||||
| -rw-r--r-- | library/std/src/sync/rwlock/tests.rs | 247 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/abi/tls.rs | 116 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/abi/tls/sync_bitset.rs | 85 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs | 25 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/rwlock.rs | 50 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/rwlock/tests.rs | 43 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/waitqueue.rs | 398 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/waitqueue/spin_mutex.rs | 76 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs | 23 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/waitqueue/tests.rs | 20 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/waitqueue/unsafe_list.rs | 146 | ||||
| -rw-r--r-- | library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs | 103 | ||||
| -rw-r--r-- | library/std/src/sys/unix/ext/fs.rs | 7 | ||||
| -rw-r--r-- | library/std/src/sys/unix/ext/net.rs | 382 | ||||
| -rw-r--r-- | library/std/src/sys/unix/ext/net/tests.rs | 374 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fd.rs | 16 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fd/tests.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sys/unix/os.rs | 30 | ||||
| -rw-r--r-- | library/std/src/sys/unix/os/tests.rs | 23 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_common.rs | 71 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_common/tests.rs | 64 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/net.rs | 30 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/net/tests.rs | 23 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/alloc.rs | 43 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/args.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/ext/fs.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/ext/io.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/ext/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/fd.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/fs.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/io.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/net.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/os.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/pipe.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/process.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/stdio.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/thread.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/time.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/windows/args.rs | 69 | ||||
| -rw-r--r-- | library/std/src/sys/windows/args/tests.rs | 61 | ||||
| -rw-r--r-- | library/std/src/sys/windows/os.rs | 20 | ||||
| -rw-r--r-- | library/std/src/sys/windows/os/tests.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/windows/process.rs | 41 | ||||
| -rw-r--r-- | library/std/src/sys/windows/process/tests.rs | 31 | ||||
| -rw-r--r-- | library/std/src/sys_common/bytestring.rs | 26 | ||||
| -rw-r--r-- | library/std/src/sys_common/bytestring/tests.rs | 19 | ||||
| -rw-r--r-- | library/std/src/sys_common/mod.rs | 8 | ||||
| -rw-r--r-- | library/std/src/sys_common/net.rs | 26 | ||||
| -rw-r--r-- | library/std/src/sys_common/net/tests.rs | 19 | ||||
| -rw-r--r-- | library/std/src/sys_common/remutex.rs | 79 | ||||
| -rw-r--r-- | library/std/src/sys_common/remutex/tests.rs | 72 | ||||
| -rw-r--r-- | library/std/src/sys_common/tests.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys_common/thread_local_key.rs | 41 | ||||
| -rw-r--r-- | library/std/src/sys_common/thread_local_key/tests.rs | 34 | ||||
| -rw-r--r-- | library/std/src/sys_common/wtf8.rs | 407 | ||||
| -rw-r--r-- | library/std/src/sys_common/wtf8/tests.rs | 397 | ||||
| -rw-r--r-- | library/std/src/thread/local.rs | 206 | ||||
| -rw-r--r-- | library/std/src/thread/local/dynamic_tests.rs | 40 | ||||
| -rw-r--r-- | library/std/src/thread/local/tests.rs | 154 | ||||
| -rw-r--r-- | library/std/src/thread/mod.rs | 273 | ||||
| -rw-r--r-- | library/std/src/thread/tests.rs | 262 | ||||
| -rw-r--r-- | library/std/src/time.rs | 172 | ||||
| -rw-r--r-- | library/std/src/time/tests.rs | 165 | ||||
| -rw-r--r-- | src/README.md | 2 | ||||
| -rw-r--r-- | src/bootstrap/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/bootstrap/README.md | 2 | ||||
| -rw-r--r-- | src/bootstrap/builder.rs | 8 | ||||
| -rw-r--r-- | src/bootstrap/builder/tests.rs | 4 | ||||
| -rw-r--r-- | src/bootstrap/compile.rs | 6 | ||||
| -rw-r--r-- | src/bootstrap/config.rs | 7 | ||||
| -rw-r--r-- | src/bootstrap/dist.rs | 2 | ||||
| -rw-r--r-- | src/bootstrap/doc.rs | 1 | ||||
| -rw-r--r-- | src/bootstrap/flags.rs | 2 | ||||
| -rw-r--r-- | src/bootstrap/lib.rs | 39 | ||||
| -rw-r--r-- | src/bootstrap/native.rs | 8 | ||||
| -rw-r--r-- | src/bootstrap/sanity.rs | 40 | ||||
| -rw-r--r-- | src/bootstrap/test.rs | 2 | ||||
| -rw-r--r-- | src/build_helper/Cargo.toml | 1 | ||||
| m--------- | src/doc/book | 0 | ||||
| m--------- | src/doc/edition-guide | 0 | ||||
| m--------- | src/doc/reference | 0 | ||||
| m--------- | src/doc/rust-by-example | 0 | ||||
| -rw-r--r-- | src/doc/rustc/src/codegen-options/index.md | 20 | ||||
| -rw-r--r-- | src/doc/rustdoc/src/lints.md | 2 | ||||
| -rw-r--r-- | src/librustc_ast/Cargo.toml | 21 | ||||
| -rw-r--r-- | src/librustc_ast_lowering/Cargo.toml | 24 | ||||
| -rw-r--r-- | src/librustc_ast_passes/Cargo.toml | 22 | ||||
| -rw-r--r-- | src/librustc_ast_pretty/Cargo.toml | 16 | ||||
| -rw-r--r-- | src/librustc_attr/Cargo.toml | 23 | ||||
| -rw-r--r-- | src/librustc_builtin_macros/Cargo.toml | 26 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/Cargo.toml | 36 | ||||
| -rw-r--r-- | src/librustc_codegen_ssa/Cargo.toml | 38 | ||||
| -rw-r--r-- | src/librustc_data_structures/jobserver.rs | 42 | ||||
| -rw-r--r-- | src/librustc_driver/Cargo.toml | 43 | ||||
| -rw-r--r-- | src/librustc_expand/Cargo.toml | 28 | ||||
| -rw-r--r-- | src/librustc_expand/parse/lexer/tests.rs | 252 | ||||
| -rw-r--r-- | src/librustc_feature/Cargo.toml | 15 | ||||
| -rw-r--r-- | src/librustc_hir/Cargo.toml | 22 | ||||
| -rw-r--r-- | src/librustc_hir_pretty/Cargo.toml | 17 | ||||
| -rw-r--r-- | src/librustc_incremental/Cargo.toml | 24 | ||||
| -rw-r--r-- | src/librustc_infer/Cargo.toml | 26 | ||||
| -rw-r--r-- | src/librustc_interface/Cargo.toml | 57 | ||||
| -rw-r--r-- | src/librustc_lexer/src/tests.rs | 167 | ||||
| -rw-r--r-- | src/librustc_lint/Cargo.toml | 26 | ||||
| -rw-r--r-- | src/librustc_llvm/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/librustc_metadata/Cargo.toml | 35 | ||||
| -rw-r--r-- | src/librustc_middle/Cargo.toml | 35 | ||||
| -rw-r--r-- | src/librustc_middle/ty/print/obsolete.rs | 251 | ||||
| -rw-r--r-- | src/librustc_mir/Cargo.toml | 35 | ||||
| -rw-r--r-- | src/librustc_mir_build/Cargo.toml | 29 | ||||
| -rw-r--r-- | src/librustc_parse/Cargo.toml | 24 | ||||
| -rw-r--r-- | src/librustc_parse_format/Cargo.toml | 13 | ||||
| -rw-r--r-- | src/librustc_passes/Cargo.toml | 23 | ||||
| -rw-r--r-- | src/librustc_plugin_impl/Cargo.toml | 21 | ||||
| -rw-r--r-- | src/librustc_privacy/Cargo.toml | 20 | ||||
| -rw-r--r-- | src/librustc_query_system/Cargo.toml | 23 | ||||
| -rw-r--r-- | src/librustc_resolve/Cargo.toml | 31 | ||||
| -rw-r--r-- | src/librustc_save_analysis/Cargo.toml | 24 | ||||
| -rw-r--r-- | src/librustc_session/Cargo.toml | 24 | ||||
| -rw-r--r-- | src/librustc_span/Cargo.toml | 23 | ||||
| -rw-r--r-- | src/librustc_symbol_mangling/Cargo.toml | 23 | ||||
| -rw-r--r-- | src/librustc_target/Cargo.toml | 18 | ||||
| -rw-r--r-- | src/librustc_trait_selection/Cargo.toml | 27 | ||||
| -rw-r--r-- | src/librustc_traits/Cargo.toml | 23 | ||||
| -rw-r--r-- | src/librustc_ty/Cargo.toml | 21 | ||||
| -rw-r--r-- | src/librustc_typeck/Cargo.toml | 29 | ||||
| -rw-r--r-- | src/librustdoc/Cargo.toml | 3 | ||||
| -rw-r--r-- | src/librustdoc/clean/blanket_impl.rs | 3 | ||||
| -rw-r--r-- | src/librustdoc/clean/cfg/tests.rs | 13 | ||||
| -rw-r--r-- | src/librustdoc/clean/utils.rs | 5 | ||||
| -rw-r--r-- | src/librustdoc/config.rs | 6 | ||||
| -rw-r--r-- | src/librustdoc/core.rs | 7 | ||||
| -rw-r--r-- | src/librustdoc/html/format.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/highlight.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/highlight/tests.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/layout.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 3 | ||||
| -rw-r--r-- | src/librustdoc/html/markdown/tests.rs | 35 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 172 | ||||
| -rw-r--r-- | src/librustdoc/html/sources.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/static/main.js | 12 | ||||
| -rw-r--r-- | src/librustdoc/html/static/themes/ayu.css | 3 | ||||
| -rw-r--r-- | src/librustdoc/lib.rs | 22 | ||||
| -rw-r--r-- | src/librustdoc/passes/check_code_block_syntax.rs | 75 | ||||
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/passes/mod.rs | 3 | ||||
| -rw-r--r-- | src/librustdoc/passes/strip_private.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/cross-crate-generic-functions.rs | 10 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/cross-crate-trait-method.rs | 22 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs | 14 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/function-as-argument.rs | 23 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/generic-drop-glue.rs | 24 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/generic-functions.rs | 28 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/generic-impl.rs | 36 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs | 4 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/instantiation-through-vtable.rs | 14 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/items-within-generic-items.rs | 12 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/non-generic-drop-glue.rs | 10 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/non-generic-functions.rs | 24 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/overloaded-operators.rs | 12 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/static-init.rs | 6 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/statics-and-consts.rs | 12 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/trait-implementations.rs | 22 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/trait-method-as-argument.rs | 31 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/trait-method-default-impl.rs | 18 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/transitive-drop-glue.rs | 26 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/tuple-drop-glue.rs | 12 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/unreferenced-const-fn.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/unsizing.rs | 18 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/unused-traits-and-generics.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/extern-drop-glue.rs | 10 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/extern-generic.rs | 14 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/incremental-merging.rs | 9 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/inlining-from-extern-crate.rs | 10 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-drop-glue.rs | 14 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-generic.rs | 17 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-inlining-but-not-all.rs | 8 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-inlining.rs | 8 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-transitive-inlining.rs | 8 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/regular-modules.rs | 43 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/shared-generics.rs | 4 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/statics.rs | 20 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/vtable-through-const.rs | 24 | ||||
| -rw-r--r-- | src/test/codegen-units/polymorphization/unused_type_parameters.rs | 147 | ||||
| -rw-r--r-- | src/test/codegen/enum-bounds-check-derived-idx.rs | 25 | ||||
| -rw-r--r-- | src/test/codegen/enum-bounds-check-issue-13926.rs | 19 | ||||
| -rw-r--r-- | src/test/codegen/enum-bounds-check.rs | 12 | ||||
| -rw-r--r-- | src/test/mir-opt/inline/inline-async.rs | 18 | ||||
| -rw-r--r-- | src/test/mir-opt/spanview-block.rs | 5 | ||||
| -rw-r--r-- | src/test/mir-opt/spanview-statement.rs | 5 | ||||
| -rw-r--r-- | src/test/mir-opt/spanview-terminator.rs | 5 | ||||
| -rw-r--r-- | src/test/mir-opt/spanview_block.main.mir_map.0.html | 67 | ||||
| -rw-r--r-- | src/test/mir-opt/spanview_statement.main.mir_map.0.html | 67 | ||||
| -rw-r--r-- | src/test/mir-opt/spanview_terminator.main.mir_map.0.html | 66 | ||||
| -rw-r--r-- | src/test/rustdoc/index-page.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/codemap_tests/bad-format-args.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/codemap_tests/bad-format-args.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/const-generics/argument_order.full.stderr (renamed from src/test/ui/const-generics/argument_order.stderr) | 4 | ||||
| -rw-r--r-- | src/test/ui/const-generics/argument_order.min.stderr | 30 | ||||
| -rw-r--r-- | src/test/ui/const-generics/argument_order.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/array-wrapper-struct-ctor.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/array-wrapper-struct-ctor.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/cannot-infer-type-for-const-param.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr (renamed from src/test/ui/const-generics/const-arg-type-arg-misordered.stderr) | 2 | ||||
| -rw-r--r-- | src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/const-generics/const-arg-type-arg-misordered.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/const-param-before-other-params.full.stderr (renamed from src/test/ui/const-generics/const-param-before-other-params.stderr) | 2 | ||||
| -rw-r--r-- | src/test/ui/const-generics/const-param-before-other-params.min.stderr | 32 | ||||
| -rw-r--r-- | src/test/ui/const-generics/const-param-before-other-params.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-64494.full.stderr (renamed from src/test/ui/const-generics/issues/issue-64494.stderr) | 4 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-64494.min.stderr | 28 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-64494.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-64519.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-66205.full.stderr | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-66205.min.stderr | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-66205.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-66205.stderr | 19 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-66906.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-66906.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-67185-1.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-67185-1.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68596.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68615-adt.min.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68615-adt.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68615-array.min.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68615-array.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68977.full.stderr | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68977.min.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68977.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-68977.stderr | 19 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-70125-1.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-70125-1.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-70125-2.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-70125-2.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-70167.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-70167.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71169.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71169.stderr) | 4 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71169.min.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71169.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71381.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71381.stderr) | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71381.min.stderr | 27 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71381.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71382.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71382.stderr) | 2 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71382.min.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71382.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71611.full.stderr (renamed from src/test/ui/const-generics/issues/issue-71611.stderr) | 4 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71611.min.stderr | 15 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-71611.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-72352.full.stderr (renamed from src/test/ui/const-generics/issues/issue-72352.stderr) | 2 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-72352.min.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-72352.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-73491.min.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-73491.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-73508.full.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-73508.min.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-73508.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-73508.stderr | 17 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-74101.min.stderr | 20 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-74101.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-74255.min.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-74255.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-75047.min.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-75047.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue70273-assoc-fn.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/std/const-generics-range.min.stderr | 56 | ||||
| -rw-r--r-- | src/test/ui/const-generics/std/const-generics-range.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-after-const-ok.min.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-after-const-ok.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-61936.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-63695.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-67144-1.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-67144-2.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-69816.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-70217.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-70507.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-70586.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71348.min.stderr | 20 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71348.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71382.full.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71382.min.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71382.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71382.stderr | 17 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-71805.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/issue-73730.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/non-local.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/qpath.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/simple.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr | 14 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr | 14 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/type-mismatch.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/type-dependent/type-mismatch.stderr | 23 | ||||
| -rw-r--r-- | src/test/ui/const-generics/types-mismatch-const-args.full.stderr (renamed from src/test/ui/const-generics/types-mismatch-const-args.stderr) | 15 | ||||
| -rw-r--r-- | src/test/ui/const-generics/types-mismatch-const-args.min.stderr | 25 | ||||
| -rw-r--r-- | src/test/ui/const-generics/types-mismatch-const-args.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/consts/cow-is-borrowed.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/consts/std/net/ipv4.rs | 58 | ||||
| -rw-r--r-- | src/test/ui/consts/std/net/ipv6.rs | 53 | ||||
| -rw-r--r-- | src/test/ui/error-codes/E0070.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/fmt/incorrect-separator.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/fmt/incorrect-separator.stderr | 44 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-13407.stderr | 12 | ||||
| -rw-r--r-- | src/test/ui/macros/duplicate-builtin.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/macros/duplicate-builtin.stderr | 21 | ||||
| -rw-r--r-- | src/test/ui/macros/missing-comma.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/macros/missing-comma.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/macros/unknown-builtin.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/macros/unknown-builtin.stderr | 9 | ||||
| -rw-r--r-- | src/test/ui/parser/shebang/shebang-doc-comment.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/parser/shebang/shebang-doc-comment.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/parser/unicode-quote-chars.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/parser/unicode-quote-chars.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/pattern/const-pat-ice.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/issue-75930-derive-cfg.rs | 30 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/issue-75930-derive-cfg.stdout | 221 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/load-panic-backtrace.rs | 21 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/load-panic-backtrace.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr | 20 | ||||
| -rw-r--r-- | src/test/ui/suggestions/if-let-typo.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/suggestions/if-let-typo.stderr | 60 | ||||
| -rw-r--r-- | src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/type/type-check/assignment-expected-bool.stderr | 114 | ||||
| -rw-r--r-- | src/test/ui/type/type-check/assignment-in-if.stderr | 64 | ||||
| m--------- | src/tools/cargo | 0 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/utils/ast_utils.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/tests/ui/issue-3145.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/tests/ui/issue-3145.stderr | 4 | ||||
| -rw-r--r-- | src/tools/error_index_generator/build.rs | 4 | ||||
| m--------- | src/tools/miri | 16 | ||||
| m--------- | src/tools/rust-analyzer | 38 | ||||
| -rw-r--r-- | src/tools/tidy/src/debug_artifacts.rs | 2 | ||||
| -rw-r--r-- | src/tools/tidy/src/edition.rs | 1 | ||||
| -rw-r--r-- | src/tools/tidy/src/features.rs | 20 | ||||
| -rw-r--r-- | src/tools/tidy/src/main.rs | 47 | ||||
| -rw-r--r-- | src/tools/tidy/src/pal.rs | 5 | ||||
| -rw-r--r-- | src/tools/tidy/src/unit_tests.rs | 14 | ||||
| -rw-r--r-- | src/tools/unstable-book-gen/src/main.rs | 10 |
2098 files changed, 22597 insertions, 20969 deletions
diff --git a/Cargo.lock b/Cargo.lock index ffc1f0dec1d..f94d95d2dc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -278,7 +278,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da" [[package]] name = "cargo" -version = "0.48.0" +version = "0.49.0" dependencies = [ "anyhow", "atty", @@ -998,9 +998,9 @@ dependencies = [ [[package]] name = "expect-test" -version = "0.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e383741ea1982866572109d1a8c807bd36aad91fca701489fdca56ef92b3b8" +checksum = "ceb96f3eaa0d4e8769c52dacfd4eb60183b817ed2f176171b3c691d5022b0f2e" dependencies = [ "difference", "once_cell", @@ -3417,10 +3417,8 @@ dependencies = [ "ena", "indexmap", "jobserver", - "lazy_static", "libc", "measureme", - "once_cell", "parking_lot 0.10.2", "rustc-hash", "rustc-rayon", @@ -3441,7 +3439,6 @@ dependencies = [ name = "rustc_driver" version = "0.0.0" dependencies = [ - "lazy_static", "libc", "rustc_ast", "rustc_ast_pretty", @@ -3515,7 +3512,6 @@ dependencies = [ name = "rustc_feature" version = "0.0.0" dependencies = [ - "lazy_static", "rustc_data_structures", "rustc_span", ] @@ -3532,7 +3528,6 @@ version = "0.0.0" name = "rustc_hir" version = "0.0.0" dependencies = [ - "lazy_static", "rustc_ast", "rustc_data_structures", "rustc_index", @@ -3607,7 +3602,6 @@ name = "rustc_interface" version = "0.0.0" dependencies = [ "libc", - "once_cell", "rustc-rayon", "rustc_ast", "rustc_ast_lowering", diff --git a/Cargo.toml b/Cargo.toml index d8d9cc399c8..fde1cb5a35c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,7 @@ [workspace] members = [ "src/bootstrap", - "src/rustc", - "src/librustc_codegen_llvm", + "compiler/rustc", "library/std", "library/test", "src/tools/cargotest", diff --git a/README.md b/README.md index fe9776bc5f8..a7e23d8ac2c 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ build. # Install build tools needed for Rust. If you're building a 32-bit compiler, # then replace "x86_64" below with "i686". If you've already got git, python, # or CMake installed and in PATH you can remove them from this list. Note - # that it is important that you do **not** use the 'python2' and 'cmake' + # that it is important that you do **not** use the 'python2', 'cmake' and 'ninja' # packages from the 'msys2' subsystem. The build has historically been known # to fail with these packages. $ pacman -S git \ @@ -121,7 +121,8 @@ build. tar \ mingw-w64-x86_64-python \ mingw-w64-x86_64-cmake \ - mingw-w64-x86_64-gcc + mingw-w64-x86_64-gcc \ + mingw-w64-x86_64-ninja ``` 4. Navigate to Rust's source code (or clone it), then build it: @@ -210,11 +211,17 @@ fetch snapshots, and an OS that can execute the available snapshot binaries. Snapshot binaries are currently built and tested on several platforms: -| Platform / Architecture | x86 | x86_64 | -|----------------------------|-----|--------| -| Windows (7, 8, 10, ...) | ✓ | ✓ | -| Linux (2.6.18 or later) | ✓ | ✓ | -| macOS (10.7 Lion or later) | ✓ | ✓ | +| Platform / Architecture | x86 | x86_64 | +|---------------------------------------------|-----|--------| +| Windows (7, 8, 10, ...) | ✓ | ✓ | +| Linux (kernel 2.6.32, glibc 2.11 or later) | ✓ | ✓ | +| macOS (10.7 Lion or later) | (\*) | ✓ | + +(\*): Apple dropped support for running 32-bit binaries starting from macOS 10.15 and iOS 11. +Due to this decision from Apple, the targets are no longer useful to our users. +Please read [our blog post][macx32] for more info. + +[macx32]: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html You may find that other platforms work, but these are our officially supported build environments that are most likely to work. diff --git a/RELEASES.md b/RELEASES.md index 64fe2df3c49..0f59d72bd16 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -10,7 +10,7 @@ Language function's caller's location information for panic messages.][72445] - [Recursively indexing into tuples no longer needs parentheses.][71322] E.g. `x.0.0` over `(x.0).0`. -- [`mem::transmute` can now be used in static and constants.][72920] **Note** +- [`mem::transmute` can now be used in statics and constants.][72920] **Note** You currently can't use `mem::transmute` in constant functions. Compiler diff --git a/src/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 5e0f167bb38..cf011e63e02 100644 --- a/src/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -4,16 +4,12 @@ name = "rustc-main" version = "0.0.0" edition = '2018' -[[bin]] -name = "rustc_binary" -path = "rustc.rs" - [dependencies] -rustc_driver = { path = "../librustc_driver" } +rustc_driver = { path = "../rustc_driver" } # Make sure rustc_codegen_ssa ends up in the sysroot, because this # crate is intended to be used by codegen backends, which may not be in-tree. -rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } +rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } [dependencies.jemalloc-sys] version = '0.3.0' diff --git a/src/rustc/rustc.rs b/compiler/rustc/src/main.rs index 6bc5aa6382c..6bc5aa6382c 100644 --- a/src/rustc/rustc.rs +++ b/compiler/rustc/src/main.rs diff --git a/src/librustc_apfloat/Cargo.toml b/compiler/rustc_apfloat/Cargo.toml index 726965e1e71..306513f1a7e 100644 --- a/src/librustc_apfloat/Cargo.toml +++ b/compiler/rustc_apfloat/Cargo.toml @@ -4,10 +4,6 @@ name = "rustc_apfloat" version = "0.0.0" edition = "2018" -[lib] -name = "rustc_apfloat" -path = "lib.rs" - [dependencies] bitflags = "1.2.1" smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_apfloat/ieee.rs b/compiler/rustc_apfloat/src/ieee.rs index e3d941cad7a..e3d941cad7a 100644 --- a/src/librustc_apfloat/ieee.rs +++ b/compiler/rustc_apfloat/src/ieee.rs diff --git a/src/librustc_apfloat/lib.rs b/compiler/rustc_apfloat/src/lib.rs index ba3adc4a135..ba3adc4a135 100644 --- a/src/librustc_apfloat/lib.rs +++ b/compiler/rustc_apfloat/src/lib.rs diff --git a/src/librustc_apfloat/ppc.rs b/compiler/rustc_apfloat/src/ppc.rs index 4ae8edf3157..4ae8edf3157 100644 --- a/src/librustc_apfloat/ppc.rs +++ b/compiler/rustc_apfloat/src/ppc.rs diff --git a/src/librustc_apfloat/tests/ieee.rs b/compiler/rustc_apfloat/tests/ieee.rs index 2d8bb7d1e8e..2d8bb7d1e8e 100644 --- a/src/librustc_apfloat/tests/ieee.rs +++ b/compiler/rustc_apfloat/tests/ieee.rs diff --git a/src/librustc_apfloat/tests/ppc.rs b/compiler/rustc_apfloat/tests/ppc.rs index 5a8de71cb34..5a8de71cb34 100644 --- a/src/librustc_apfloat/tests/ppc.rs +++ b/compiler/rustc_apfloat/tests/ppc.rs diff --git a/src/librustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index dfae956e2b6..41701f3255f 100644 --- a/src/librustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -4,10 +4,6 @@ name = "rustc_arena" version = "0.0.0" edition = "2018" -[lib] -name = "rustc_arena" -path = "lib.rs" - [dependencies] -rustc_data_structures = { path = "../librustc_data_structures" } +rustc_data_structures = { path = "../rustc_data_structures" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_arena/lib.rs b/compiler/rustc_arena/src/lib.rs index 5e6a0340d12..5e6a0340d12 100644 --- a/src/librustc_arena/lib.rs +++ b/compiler/rustc_arena/src/lib.rs diff --git a/src/librustc_arena/tests.rs b/compiler/rustc_arena/src/tests.rs index 8e63bdf5458..8e63bdf5458 100644 --- a/src/librustc_arena/tests.rs +++ b/compiler/rustc_arena/src/tests.rs diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml new file mode 100644 index 00000000000..13e17a807c4 --- /dev/null +++ b/compiler/rustc_ast/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_serialize = { path = "../rustc_serialize" } +tracing = "0.1" +rustc_span = { path = "../rustc_span" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +bitflags = "1.2.1" diff --git a/src/librustc_ast/README.md b/compiler/rustc_ast/README.md index dd407dba1f4..dd407dba1f4 100644 --- a/src/librustc_ast/README.md +++ b/compiler/rustc_ast/README.md diff --git a/src/librustc_ast/ast.rs b/compiler/rustc_ast/src/ast.rs index 127a53cad2b..49aa1fc1735 100644 --- a/src/librustc_ast/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -922,9 +922,13 @@ impl Stmt { pub fn add_trailing_semicolon(mut self) -> Self { self.kind = match self.kind { StmtKind::Expr(expr) => StmtKind::Semi(expr), - StmtKind::MacCall(mac) => StmtKind::MacCall( - mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)), - ), + StmtKind::MacCall(mac) => { + StmtKind::MacCall(mac.map(|MacCallStmt { mac, style: _, attrs }| MacCallStmt { + mac, + style: MacStmtStyle::Semicolon, + attrs, + })) + } kind => kind, }; self @@ -958,7 +962,14 @@ pub enum StmtKind { /// Just a trailing semi-colon. Empty, /// Macro. - MacCall(P<(MacCall, MacStmtStyle, AttrVec)>), + MacCall(P<MacCallStmt>), +} + +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct MacCallStmt { + pub mac: MacCall, + pub style: MacStmtStyle, + pub attrs: AttrVec, } #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)] diff --git a/src/librustc_ast/ast/tests.rs b/compiler/rustc_ast/src/ast/tests.rs index 8ba55bf037b..8ba55bf037b 100644 --- a/src/librustc_ast/ast/tests.rs +++ b/compiler/rustc_ast/src/ast/tests.rs diff --git a/src/librustc_ast/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index edcbce3e2cf..12d6f7cc33d 100644 --- a/src/librustc_ast/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -16,7 +16,6 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use std::iter; -use std::ops::DerefMut; pub struct MarkedAttrs(GrowableBitSet<AttrId>); @@ -634,10 +633,7 @@ impl HasAttrs for StmtKind { StmtKind::Local(ref local) => local.attrs(), StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(), StmtKind::Empty | StmtKind::Item(..) => &[], - StmtKind::MacCall(ref mac) => { - let (_, _, ref attrs) = **mac; - attrs.attrs() - } + StmtKind::MacCall(ref mac) => mac.attrs.attrs(), } } @@ -647,8 +643,7 @@ impl HasAttrs for StmtKind { StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), StmtKind::Empty | StmtKind::Item(..) => {} StmtKind::MacCall(mac) => { - let (_mac, _style, attrs) = mac.deref_mut(); - attrs.visit_attrs(f); + mac.attrs.visit_attrs(f); } } } diff --git a/src/librustc_ast/crate_disambiguator.rs b/compiler/rustc_ast/src/crate_disambiguator.rs index bd7d8516714..bd7d8516714 100644 --- a/src/librustc_ast/crate_disambiguator.rs +++ b/compiler/rustc_ast/src/crate_disambiguator.rs diff --git a/src/librustc_ast/entry.rs b/compiler/rustc_ast/src/entry.rs index 290f6006de0..290f6006de0 100644 --- a/src/librustc_ast/entry.rs +++ b/compiler/rustc_ast/src/entry.rs diff --git a/src/librustc_ast/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index cd27f958e46..cd27f958e46 100644 --- a/src/librustc_ast/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs diff --git a/src/librustc_ast/expand/mod.rs b/compiler/rustc_ast/src/expand/mod.rs index eebfc38bdf4..eebfc38bdf4 100644 --- a/src/librustc_ast/expand/mod.rs +++ b/compiler/rustc_ast/src/expand/mod.rs diff --git a/src/librustc_ast/lib.rs b/compiler/rustc_ast/src/lib.rs index b556c1a446b..b556c1a446b 100644 --- a/src/librustc_ast/lib.rs +++ b/compiler/rustc_ast/src/lib.rs diff --git a/src/librustc_ast/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 965571aaa54..3ef83ef3fc9 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1305,7 +1305,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>( StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), StmtKind::Empty => smallvec![StmtKind::Empty], StmtKind::MacCall(mut mac) => { - let (mac_, _semi, attrs) = mac.deref_mut(); + let MacCallStmt { mac: mac_, style: _, attrs } = mac.deref_mut(); vis.visit_mac(mac_); visit_thin_attrs(attrs, vis); smallvec![StmtKind::MacCall(mac)] diff --git a/src/librustc_ast/node_id.rs b/compiler/rustc_ast/src/node_id.rs index 1035e945538..1035e945538 100644 --- a/src/librustc_ast/node_id.rs +++ b/compiler/rustc_ast/src/node_id.rs diff --git a/src/librustc_ast/ptr.rs b/compiler/rustc_ast/src/ptr.rs index e4a3cccb7ea..e4a3cccb7ea 100644 --- a/src/librustc_ast/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs diff --git a/src/librustc_ast/token.rs b/compiler/rustc_ast/src/token.rs index 4a8bf6b4f19..c6cc890b47f 100644 --- a/src/librustc_ast/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -251,17 +251,6 @@ pub enum TokenKind { /// similarly to symbols in string literal tokens. DocComment(CommentKind, ast::AttrStyle, Symbol), - // Junk. These carry no data because we don't really care about the data - // they *would* carry, and don't really want to allocate a new ident for - // them. Instead, users could extract that from the associated span. - /// Whitespace. - Whitespace, - /// A comment. - Comment, - Shebang(Symbol), - /// A completely invalid token which should be skipped. - Unknown(Symbol), - Eof, } @@ -331,7 +320,7 @@ impl Token { /// Some token that will be thrown away later. pub fn dummy() -> Self { - Token::new(TokenKind::Whitespace, DUMMY_SP) + Token::new(TokenKind::Question, DUMMY_SP) } /// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary. @@ -360,7 +349,7 @@ impl Token { pub fn is_op(&self) -> bool { match self.kind { OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) - | Lifetime(..) | Interpolated(..) | Whitespace | Comment | Shebang(..) | Eof => false, + | Lifetime(..) | Interpolated(..) | Eof => false, _ => true, } } @@ -676,8 +665,7 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) - | Lifetime(..) | Interpolated(..) | DocComment(..) | Whitespace | Comment - | Shebang(..) | Unknown(..) | Eof => return None, + | Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None, }; Some(Token::new(kind, self.span.to(joint.span))) diff --git a/src/librustc_ast/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 151acddae84..151acddae84 100644 --- a/src/librustc_ast/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs diff --git a/src/librustc_ast/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 60422a2e573..60422a2e573 100644 --- a/src/librustc_ast/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs diff --git a/src/librustc_ast/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index e97c8cc4562..e97c8cc4562 100644 --- a/src/librustc_ast/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs diff --git a/src/librustc_ast/util/comments/tests.rs b/compiler/rustc_ast/src/util/comments/tests.rs index e19198f863b..e19198f863b 100644 --- a/src/librustc_ast/util/comments/tests.rs +++ b/compiler/rustc_ast/src/util/comments/tests.rs diff --git a/src/librustc_ast/util/lev_distance.rs b/compiler/rustc_ast/src/util/lev_distance.rs index d4e0e3ba051..d4e0e3ba051 100644 --- a/src/librustc_ast/util/lev_distance.rs +++ b/compiler/rustc_ast/src/util/lev_distance.rs diff --git a/src/librustc_ast/util/lev_distance/tests.rs b/compiler/rustc_ast/src/util/lev_distance/tests.rs index 7ebedbcb76a..7ebedbcb76a 100644 --- a/src/librustc_ast/util/lev_distance/tests.rs +++ b/compiler/rustc_ast/src/util/lev_distance/tests.rs diff --git a/src/librustc_ast/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 597e5b437fc..597e5b437fc 100644 --- a/src/librustc_ast/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs diff --git a/src/librustc_ast/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 2ee94965756..2ee94965756 100644 --- a/src/librustc_ast/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs diff --git a/src/librustc_ast/visit.rs b/compiler/rustc_ast/src/visit.rs index b65a88cb90e..234ce280f97 100644 --- a/src/librustc_ast/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -692,7 +692,7 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), StmtKind::Empty => {} StmtKind::MacCall(ref mac) => { - let (ref mac, _, ref attrs) = **mac; + let MacCallStmt { ref mac, style: _, ref attrs } = **mac; visitor.visit_mac(mac); for attr in attrs.iter() { visitor.visit_attribute(attr); diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml new file mode 100644 index 00000000000..177a9066edf --- /dev/null +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast_lowering" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_arena = { path = "../rustc_arena" } +tracing = "0.1" +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_hir = { path = "../rustc_hir" } +rustc_target = { path = "../rustc_target" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } +rustc_span = { path = "../rustc_span" } +rustc_errors = { path = "../rustc_errors" } +rustc_session = { path = "../rustc_session" } +rustc_ast = { path = "../rustc_ast" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_ast_lowering/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index df452825bba..df452825bba 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs diff --git a/src/librustc_ast_lowering/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f3309afec7d..f3309afec7d 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs diff --git a/src/librustc_ast_lowering/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 586355fe613..586355fe613 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs diff --git a/src/librustc_ast_lowering/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index cb7b7c0eb61..cb7b7c0eb61 100644 --- a/src/librustc_ast_lowering/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs diff --git a/src/librustc_ast_lowering/path.rs b/compiler/rustc_ast_lowering/src/path.rs index cf68dfb9ae1..cf68dfb9ae1 100644 --- a/src/librustc_ast_lowering/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml new file mode 100644 index 00000000000..7cf3e752c92 --- /dev/null +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -0,0 +1,18 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast_passes" +version = "0.0.0" +edition = "2018" + +[dependencies] +itertools = "0.8" +tracing = "0.1" +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_parse = { path = "../rustc_parse" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rustc_ast = { path = "../rustc_ast" } diff --git a/src/librustc_ast_passes/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index a01dd8c939c..a01dd8c939c 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs diff --git a/src/librustc_ast_passes/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 0ee8ef55e61..0ee8ef55e61 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs diff --git a/src/librustc_ast_passes/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index bfe30441980..bfe30441980 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs diff --git a/src/librustc_ast_passes/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index 706dca2b7f4..706dca2b7f4 100644 --- a/src/librustc_ast_passes/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs diff --git a/src/librustc_ast_passes/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs index 053aba86222..053aba86222 100644 --- a/src/librustc_ast_passes/show_span.rs +++ b/compiler/rustc_ast_passes/src/show_span.rs diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml new file mode 100644 index 00000000000..f447bc7f4ef --- /dev/null +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -0,0 +1,14 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast_pretty" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +tracing = "0.1" +rustc_span = { path = "../rustc_span" } +rustc_ast = { path = "../rustc_ast" } +rustc_target = { path = "../rustc_target" } diff --git a/src/librustc_ast_pretty/helpers.rs b/compiler/rustc_ast_pretty/src/helpers.rs index dce856df9c6..dce856df9c6 100644 --- a/src/librustc_ast_pretty/helpers.rs +++ b/compiler/rustc_ast_pretty/src/helpers.rs diff --git a/src/librustc_ast_pretty/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 9adc6c604e8..9adc6c604e8 100644 --- a/src/librustc_ast_pretty/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs diff --git a/src/librustc_ast_pretty/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index ca7f127ced6..ca7f127ced6 100644 --- a/src/librustc_ast_pretty/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs diff --git a/src/librustc_ast_pretty/pprust.rs b/compiler/rustc_ast_pretty/src/pprust.rs index cb48deb5886..9743a000429 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/compiler/rustc_ast_pretty/src/pprust.rs @@ -289,10 +289,6 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) doc_comment_to_string(comment_kind, attr_style, data) } token::Eof => "<eof>".to_string(), - token::Whitespace => " ".to_string(), - token::Comment => "/* */".to_string(), - token::Shebang(s) => format!("/* shebang: {}*/", s), - token::Unknown(s) => s.to_string(), token::Interpolated(ref nt) => nonterminal_to_string(nt), } @@ -1507,11 +1503,10 @@ impl<'a> State<'a> { self.s.word(";"); } ast::StmtKind::MacCall(ref mac) => { - let (ref mac, style, ref attrs) = **mac; self.space_if_not_bol(); - self.print_outer_attributes(attrs); - self.print_mac(mac); - if style == ast::MacStmtStyle::Semicolon { + self.print_outer_attributes(&mac.attrs); + self.print_mac(&mac.mac); + if mac.style == ast::MacStmtStyle::Semicolon { self.s.word(";"); } } diff --git a/src/librustc_ast_pretty/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs index fdbf3feb900..fdbf3feb900 100644 --- a/src/librustc_ast_pretty/pprust/tests.rs +++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml new file mode 100644 index 00000000000..5f941a0a650 --- /dev/null +++ b/compiler/rustc_attr/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_attr" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_errors = { path = "../rustc_errors" } +rustc_span = { path = "../rustc_span" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_feature = { path = "../rustc_feature" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } +rustc_session = { path = "../rustc_session" } +rustc_ast = { path = "../rustc_ast" } +version_check = "0.9" diff --git a/src/librustc_attr/builtin.rs b/compiler/rustc_attr/src/builtin.rs index b8929fe0889..b8929fe0889 100644 --- a/src/librustc_attr/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs diff --git a/src/librustc_attr/lib.rs b/compiler/rustc_attr/src/lib.rs index 149a950f7d4..149a950f7d4 100644 --- a/src/librustc_attr/lib.rs +++ b/compiler/rustc_attr/src/lib.rs diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml new file mode 100644 index 00000000000..c397a854126 --- /dev/null +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -0,0 +1,24 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_builtin_macros" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_parse_format = { path = "../rustc_parse_format" } +tracing = "0.1" +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_parse = { path = "../rustc_parse" } +rustc_target = { path = "../rustc_target" } +rustc_session = { path = "../rustc_session" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_ast = { path = "../rustc_ast" } +rustc_expand = { path = "../rustc_expand" } +rustc_span = { path = "../rustc_span" } diff --git a/src/librustc_builtin_macros/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 5dafd6b77ab..5dafd6b77ab 100644 --- a/src/librustc_builtin_macros/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs diff --git a/src/librustc_builtin_macros/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 25181715540..25181715540 100644 --- a/src/librustc_builtin_macros/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs diff --git a/src/librustc_builtin_macros/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 4c00162b556..4c00162b556 100644 --- a/src/librustc_builtin_macros/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs diff --git a/src/librustc_builtin_macros/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs index 75f4b077640..75f4b077640 100644 --- a/src/librustc_builtin_macros/cfg_accessible.rs +++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs diff --git a/src/librustc_builtin_macros/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index 34e2accc615..34e2accc615 100644 --- a/src/librustc_builtin_macros/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs diff --git a/src/librustc_builtin_macros/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs index f5955604e5f..f5955604e5f 100644 --- a/src/librustc_builtin_macros/compile_error.rs +++ b/compiler/rustc_builtin_macros/src/compile_error.rs diff --git a/src/librustc_builtin_macros/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index e5077d93674..e5077d93674 100644 --- a/src/librustc_builtin_macros/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs diff --git a/src/librustc_builtin_macros/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs index 8223cdda072..8223cdda072 100644 --- a/src/librustc_builtin_macros/concat_idents.rs +++ b/compiler/rustc_builtin_macros/src/concat_idents.rs diff --git a/src/librustc_builtin_macros/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 12ef166b8b0..12ef166b8b0 100644 --- a/src/librustc_builtin_macros/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs diff --git a/src/librustc_builtin_macros/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 957c8035399..957c8035399 100644 --- a/src/librustc_builtin_macros/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs diff --git a/src/librustc_builtin_macros/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 79f35ad5819..79f35ad5819 100644 --- a/src/librustc_builtin_macros/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs diff --git a/src/librustc_builtin_macros/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index c1473e24093..c1473e24093 100644 --- a/src/librustc_builtin_macros/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 8e9f15743cc..8e9f15743cc 100644 --- a/src/librustc_builtin_macros/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs diff --git a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 21174ca4c8b..21174ca4c8b 100644 --- a/src/librustc_builtin_macros/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs diff --git a/src/librustc_builtin_macros/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 120e859f2b1..120e859f2b1 100644 --- a/src/librustc_builtin_macros/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs diff --git a/src/librustc_builtin_macros/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index df69f6c90d8..df69f6c90d8 100644 --- a/src/librustc_builtin_macros/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs diff --git a/src/librustc_builtin_macros/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 980be3a0050..980be3a0050 100644 --- a/src/librustc_builtin_macros/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs diff --git a/src/librustc_builtin_macros/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index 62aa1cbfbf2..62aa1cbfbf2 100644 --- a/src/librustc_builtin_macros/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 849e8b136e1..849e8b136e1 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs diff --git a/src/librustc_builtin_macros/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 6b7d0e1f204..6b7d0e1f204 100644 --- a/src/librustc_builtin_macros/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs diff --git a/src/librustc_builtin_macros/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 868f863b990..868f863b990 100644 --- a/src/librustc_builtin_macros/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 7e3fd131d44..7e3fd131d44 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs diff --git a/src/librustc_builtin_macros/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 6de12acfb94..6de12acfb94 100644 --- a/src/librustc_builtin_macros/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs diff --git a/src/librustc_builtin_macros/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 373277f525d..5d6f791f137 100644 --- a/src/librustc_builtin_macros/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -135,21 +135,52 @@ fn parse_args<'a>( return Err(ecx.struct_span_err(sp, "requires at least a format string argument")); } - let fmtstr = p.parse_expr()?; + let first_token = &p.token; + let fmtstr = match first_token.kind { + token::TokenKind::Literal(token::Lit { + kind: token::LitKind::Str | token::LitKind::StrRaw(_), + .. + }) => { + // If the first token is a string literal, then a format expression + // is constructed from it. + // + // This allows us to properly handle cases when the first comma + // after the format string is mistakenly replaced with any operator, + // which cause the expression parser to eat too much tokens. + p.parse_literal_maybe_minus()? + } + _ => { + // Otherwise, we fall back to the expression parser. + p.parse_expr()? + } + }; + let mut first = true; let mut named = false; while p.token != token::Eof { if !p.eat(&token::Comma) { if first { - // After `format!(""` we always expect *only* a comma... - let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`"); - err.span_label(p.token.span, "expected `,`"); - p.maybe_annotate_with_ascription(&mut err, false); - return Err(err); - } else { - // ...after that delegate to `expect` to also include the other expected tokens. - let _ = p.expect(&token::Comma)?; + p.clear_expected_tokens(); + } + + // `Parser::expect` tries to recover using the + // `Parser::unexpected_try_recover` function. This function is able + // to recover if the expected token is a closing delimiter. + // + // As `,` is not a closing delimiter, it will always return an `Err` + // variant. + let mut err = p.expect(&token::Comma).unwrap_err(); + + match token::TokenKind::Comma.similar_tokens() { + Some(tks) if tks.contains(&p.token.kind) => { + // If a similar token is found, then it may be a typo. We + // consider it as a comma, and continue parsing. + err.emit(); + p.bump(); + } + // Otherwise stop the parsing and return the error. + _ => return Err(err), } } first = false; diff --git a/src/librustc_builtin_macros/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index 85cf4c42e94..85cf4c42e94 100644 --- a/src/librustc_builtin_macros/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs diff --git a/src/librustc_builtin_macros/format_foreign/printf/tests.rs b/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs index 33c54c9cee0..33c54c9cee0 100644 --- a/src/librustc_builtin_macros/format_foreign/printf/tests.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign/printf/tests.rs diff --git a/src/librustc_builtin_macros/format_foreign/shell/tests.rs b/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs index ed8fe81dfcd..ed8fe81dfcd 100644 --- a/src/librustc_builtin_macros/format_foreign/shell/tests.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign/shell/tests.rs diff --git a/src/librustc_builtin_macros/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 8478fcfbf09..8478fcfbf09 100644 --- a/src/librustc_builtin_macros/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs diff --git a/src/librustc_builtin_macros/global_asm.rs b/compiler/rustc_builtin_macros/src/global_asm.rs index 2465f33622e..2465f33622e 100644 --- a/src/librustc_builtin_macros/global_asm.rs +++ b/compiler/rustc_builtin_macros/src/global_asm.rs diff --git a/src/librustc_builtin_macros/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 87be6d1743a..87be6d1743a 100644 --- a/src/librustc_builtin_macros/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs diff --git a/src/librustc_builtin_macros/llvm_asm.rs b/compiler/rustc_builtin_macros/src/llvm_asm.rs index db73fdbe24f..db73fdbe24f 100644 --- a/src/librustc_builtin_macros/llvm_asm.rs +++ b/compiler/rustc_builtin_macros/src/llvm_asm.rs diff --git a/src/librustc_builtin_macros/log_syntax.rs b/compiler/rustc_builtin_macros/src/log_syntax.rs index ede34a76125..ede34a76125 100644 --- a/src/librustc_builtin_macros/log_syntax.rs +++ b/compiler/rustc_builtin_macros/src/log_syntax.rs diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 0c6769906f3..0c6769906f3 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs diff --git a/src/librustc_builtin_macros/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 70753208af3..70753208af3 100644 --- a/src/librustc_builtin_macros/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs diff --git a/src/librustc_builtin_macros/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index e801b5c7b0c..e801b5c7b0c 100644 --- a/src/librustc_builtin_macros/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs diff --git a/src/librustc_builtin_macros/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 8e56e80bba2..8e56e80bba2 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs diff --git a/src/librustc_builtin_macros/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 0ea60665d67..0ea60665d67 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs diff --git a/src/librustc_builtin_macros/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs index c17f2afe494..c17f2afe494 100644 --- a/src/librustc_builtin_macros/trace_macros.rs +++ b/compiler/rustc_builtin_macros/src/trace_macros.rs diff --git a/src/librustc_builtin_macros/util.rs b/compiler/rustc_builtin_macros/src/util.rs index 01ea80c4c8a..01ea80c4c8a 100644 --- a/src/librustc_builtin_macros/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml new file mode 100644 index 00000000000..38f552558c8 --- /dev/null +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -0,0 +1,34 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_codegen_llvm" +version = "0.0.0" +edition = "2018" + +[lib] +test = false +doctest = false + +[dependencies] +bitflags = "1.0" +libc = "0.2" +measureme = "0.7.1" +snap = "1" +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc-demangle = "0.1" +rustc_attr = { path = "../rustc_attr" } +rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_fs_util = { path = "../rustc_fs_util" } +rustc_hir = { path = "../rustc_hir" } +rustc_incremental = { path = "../rustc_incremental" } +rustc_index = { path = "../rustc_index" } +rustc_llvm = { path = "../../src/librustc_llvm" } +rustc_session = { path = "../rustc_session" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_target = { path = "../rustc_target" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } diff --git a/src/librustc_codegen_llvm/README.md b/compiler/rustc_codegen_llvm/README.md index afec60d017e..afec60d017e 100644 --- a/src/librustc_codegen_llvm/README.md +++ b/compiler/rustc_codegen_llvm/README.md diff --git a/src/librustc_codegen_llvm/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 7857ccb613b..7857ccb613b 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs diff --git a/src/librustc_codegen_llvm/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index bc1d9e1818c..bc1d9e1818c 100644 --- a/src/librustc_codegen_llvm/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs diff --git a/src/librustc_codegen_llvm/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index a468d09c2d9..a468d09c2d9 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs diff --git a/src/librustc_codegen_llvm/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 227a87ff819..227a87ff819 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs diff --git a/src/librustc_codegen_llvm/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index a115a1e9516..a115a1e9516 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs diff --git a/src/librustc_codegen_llvm/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 7c710a1cb3d..7c710a1cb3d 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs diff --git a/src/librustc_codegen_llvm/back/profiling.rs b/compiler/rustc_codegen_llvm/src/back/profiling.rs index 2741f7d848e..2741f7d848e 100644 --- a/src/librustc_codegen_llvm/back/profiling.rs +++ b/compiler/rustc_codegen_llvm/src/back/profiling.rs diff --git a/src/librustc_codegen_llvm/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 6f386c1287c..6f386c1287c 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs diff --git a/src/librustc_codegen_llvm/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 6a1b373ef07..6a1b373ef07 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs diff --git a/src/librustc_codegen_llvm/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4ece08f6293..89c3e21632e 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -6,7 +6,6 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; use libc::{c_char, c_uint}; -use rustc_codegen_ssa::base::to_immediate; use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -367,6 +366,20 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { (self.extract_value(res, 0), self.extract_value(res, 1)) } + fn from_immediate(&mut self, val: Self::Value) -> Self::Value { + if self.cx().val_ty(val) == self.cx().type_i1() { + self.zext(val, self.cx().type_i8()) + } else { + val + } + } + fn to_immediate_scalar(&mut self, val: Self::Value, scalar: &abi::Scalar) -> Self::Value { + if scalar.is_bool() { + return self.trunc(val, self.cx().type_i1()); + } + val + } + fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value { let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); @@ -471,7 +484,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } load }); - OperandValue::Immediate(to_immediate(self, llval, place.layout)) + OperandValue::Immediate(self.to_immediate(llval, place.layout)) } else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi { let b_offset = a.value.size(self).align_to(b.value.align(self).abi); @@ -479,7 +492,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let llptr = self.struct_gep(place.llval, i as u64); let load = self.load(llptr, align); scalar_load_metadata(self, load, scalar); - if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load } + self.to_immediate_scalar(load, scalar) }; OperandValue::Pair( diff --git a/src/librustc_codegen_llvm/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 4afd906fce7..4afd906fce7 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs diff --git a/src/librustc_codegen_llvm/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 0b1cf03fa7e..0b1cf03fa7e 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs diff --git a/src/librustc_codegen_llvm/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 86a5ec59254..86a5ec59254 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs diff --git a/src/librustc_codegen_llvm/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 1c51a9df5d8..1c51a9df5d8 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs diff --git a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index ec6c177614d..ec6c177614d 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs diff --git a/src/librustc_codegen_llvm/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 2bd37bf9c4f..2bd37bf9c4f 100644 --- a/src/librustc_codegen_llvm/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 7f47b61de3f..7f47b61de3f 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs diff --git a/src/librustc_codegen_llvm/debuginfo/doc.rs b/compiler/rustc_codegen_llvm/src/debuginfo/doc.rs index b3a8fa29887..b3a8fa29887 100644 --- a/src/librustc_codegen_llvm/debuginfo/doc.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/doc.rs diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 29edd66049c..29edd66049c 100644 --- a/src/librustc_codegen_llvm/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 9d92d53775c..9d92d53775c 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index b414426af8c..b414426af8c 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs index d1a55335c44..d1a55335c44 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/compiler/rustc_codegen_llvm/src/debuginfo/source_loc.rs index 66ae9d72c3e..66ae9d72c3e 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/source_loc.rs diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index ee188e69be1..ee188e69be1 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs diff --git a/src/librustc_codegen_llvm/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index ec42bd4a039..ec42bd4a039 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c1dfb83b135..951b9928cc9 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -8,7 +8,7 @@ use crate::va_arg::emit_va_arg; use crate::value::Value; use rustc_ast as ast; -use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh}; +use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::glue; @@ -301,7 +301,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMSetAlignment(load, align); } - to_immediate(self, load, self.layout_of(tp_ty)) + self.to_immediate(load, self.layout_of(tp_ty)) } sym::volatile_store => { let dst = args[0].deref(self.cx()); diff --git a/src/librustc_codegen_llvm/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 67d4b2642c0..67d4b2642c0 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs index 64db4f7462d..64db4f7462d 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/archive_ro.rs diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs index 47f5c94e70c..47f5c94e70c 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 32822eba930..32822eba930 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index c09e3659f80..c09e3659f80 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index f0b50459837..f0b50459837 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs diff --git a/src/librustc_codegen_llvm/metadata.rs b/compiler/rustc_codegen_llvm/src/metadata.rs index 9036428c04b..9036428c04b 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/metadata.rs diff --git a/src/librustc_codegen_llvm/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 992e83d08fc..992e83d08fc 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs diff --git a/src/librustc_codegen_llvm/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 3b53b4fe77b..3b53b4fe77b 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs diff --git a/src/librustc_codegen_llvm/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 40870c66475..a02601eb43e 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -4,7 +4,6 @@ use crate::type_::Type; use rustc_codegen_ssa::traits::*; use rustc_middle::bug; use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout}; -use rustc_middle::ty::print::obsolete::DefPathBasedNames; use rustc_middle::ty::{self, Ty, TypeFoldable}; use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape}; use rustc_target::abi::{Int, Pointer, F32, F64}; @@ -52,32 +51,34 @@ fn uncached_llvm_type<'a, 'tcx>( } let name = match layout.ty.kind { - ty::Closure(..) | - ty::Generator(..) | - ty::Adt(..) | // FIXME(eddyb) producing readable type names for trait objects can result // in problematically distinct types due to HRTB and subtyping (see #47638). // ty::Dynamic(..) | - ty::Foreign(..) | - ty::Str => { - let mut name = String::with_capacity(32); - let printer = DefPathBasedNames::new(cx.tcx, true, true); - printer.push_type_name(layout.ty, &mut name, false); - if let (&ty::Adt(def, _), &Variants::Single { index }) - = (&layout.ty.kind, &layout.variants) + ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str + if !cx.sess().fewer_names() => + { + let mut name = layout.ty.to_string(); + if let (&ty::Adt(def, _), &Variants::Single { index }) = + (&layout.ty.kind, &layout.variants) { if def.is_enum() && !def.variants.is_empty() { write!(&mut name, "::{}", def.variants[index].ident).unwrap(); } } - if let (&ty::Generator(_, _, _), &Variants::Single { index }) - = (&layout.ty.kind, &layout.variants) + if let (&ty::Generator(_, _, _), &Variants::Single { index }) = + (&layout.ty.kind, &layout.variants) { write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap(); } Some(name) } - _ => None + ty::Adt(..) => { + // If `Some` is returned then a named struct is created in LLVM. Name collisions are + // avoided by LLVM (with increasing suffixes). If rustc doesn't generate names then that + // can improve perf. + Some(String::new()) + } + _ => None, }; match layout.fields { diff --git a/src/librustc_codegen_llvm/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 54efa05aee8..54efa05aee8 100644 --- a/src/librustc_codegen_llvm/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs diff --git a/src/librustc_codegen_llvm/value.rs b/compiler/rustc_codegen_llvm/src/value.rs index 1338a229566..1338a229566 100644 --- a/src/librustc_codegen_llvm/value.rs +++ b/compiler/rustc_codegen_llvm/src/value.rs diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml new file mode 100644 index 00000000000..e5df0f60941 --- /dev/null +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -0,0 +1,36 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_codegen_ssa" +version = "0.0.0" +edition = "2018" + +[lib] +test = false + +[dependencies] +bitflags = "1.2.1" +cc = "1.0.1" +num_cpus = "1.0" +memmap = "0.7" +tracing = "0.1" +libc = "0.2.50" +jobserver = "0.1.11" +tempfile = "3.1" +pathdiff = "0.2.0" + +rustc_serialize = { path = "../rustc_serialize" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +rustc_middle = { path = "../rustc_middle" } +rustc_apfloat = { path = "../rustc_apfloat" } +rustc_attr = { path = "../rustc_attr" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } +rustc_data_structures = { path = "../rustc_data_structures"} +rustc_errors = { path = "../rustc_errors" } +rustc_fs_util = { path = "../rustc_fs_util" } +rustc_hir = { path = "../rustc_hir" } +rustc_incremental = { path = "../rustc_incremental" } +rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } +rustc_target = { path = "../rustc_target" } +rustc_session = { path = "../rustc_session" } diff --git a/src/librustc_codegen_ssa/README.md b/compiler/rustc_codegen_ssa/README.md index 7b770187b75..7b770187b75 100644 --- a/src/librustc_codegen_ssa/README.md +++ b/compiler/rustc_codegen_ssa/README.md diff --git a/src/librustc_codegen_ssa/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index f83b4b2b0c0..f83b4b2b0c0 100644 --- a/src/librustc_codegen_ssa/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs diff --git a/src/librustc_codegen_ssa/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs index 0208bb73abd..0208bb73abd 100644 --- a/src/librustc_codegen_ssa/back/command.rs +++ b/compiler/rustc_codegen_ssa/src/back/command.rs diff --git a/src/librustc_codegen_ssa/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index bfcf979d125..c044020d930 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1014,86 +1014,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { } } -// Because windows-gnu target is meant to be self-contained for pure Rust code it bundles -// own mingw-w64 libraries. These libraries are usually not compatible with mingw-w64 -// installed in the system. This breaks many cases where Rust is mixed with other languages -// (e.g. *-sys crates). -// We prefer system mingw-w64 libraries if they are available to avoid this issue. -fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> { - fn find_exe_in_path<P>(exe_name: P) -> Option<PathBuf> - where - P: AsRef<Path>, - { - for dir in env::split_paths(&env::var_os("PATH")?) { - let full_path = dir.join(&exe_name); - if full_path.is_file() { - return Some(fix_windows_verbatim_for_gcc(&full_path)); - } - } - None - } - - fn probe(sess: &Session) -> Option<PathBuf> { - if let (linker, LinkerFlavor::Gcc) = linker_and_flavor(&sess) { - let linker_path = if cfg!(windows) && linker.extension().is_none() { - linker.with_extension("exe") - } else { - linker - }; - if let Some(linker_path) = find_exe_in_path(linker_path) { - let mingw_arch = match &sess.target.target.arch { - x if x == "x86" => "i686", - x => x, - }; - let mingw_bits = &sess.target.target.target_pointer_width; - let mingw_dir = format!("{}-w64-mingw32", mingw_arch); - // Here we have path/bin/gcc but we need path/ - let mut path = linker_path; - path.pop(); - path.pop(); - // Loosely based on Clang MinGW driver - let probe_paths = vec![ - path.join(&mingw_dir).join("lib"), // Typical path - path.join(&mingw_dir).join("sys-root/mingw/lib"), // Rare path - path.join(format!( - "lib/mingw/tools/install/mingw{}/{}/lib", - &mingw_bits, &mingw_dir - )), // Chocolatey is creative - ]; - for probe_path in probe_paths { - if probe_path.join("crt2.o").exists() { - return Some(probe_path); - }; - } - }; - }; - None - } - - let mut system_library_path = sess.system_library_path.borrow_mut(); - match &*system_library_path { - Some(Some(compiler_libs_path)) => Some(compiler_libs_path.clone()), - Some(None) => None, - None => { - let path = probe(sess); - *system_library_path = Some(path.clone()); - path - } - } -} - fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf { - // prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details - if sess.opts.debugging_opts.link_self_contained.is_none() - && sess.target.target.llvm_target.contains("windows-gnu") - { - if let Some(compiler_libs_path) = get_crt_libs_path(sess) { - let file_path = compiler_libs_path.join(name); - if file_path.exists() { - return file_path; - } - } - } let fs = sess.target_filesearch(PathKind::Native); let file_path = fs.get_lib_path().join(name); if file_path.exists() { @@ -1286,10 +1207,32 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind { } } +// Returns true if linker is located within sysroot +fn detect_self_contained_mingw(sess: &Session) -> bool { + let (linker, _) = linker_and_flavor(&sess); + // Assume `-C linker=rust-lld` as self-contained mode + if linker == Path::new("rust-lld") { + return true; + } + let linker_with_extension = if cfg!(windows) && linker.extension().is_none() { + linker.with_extension("exe") + } else { + linker + }; + for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) { + let full_path = dir.join(&linker_with_extension); + // If linker comes from sysroot assume self-contained mode + if full_path.is_file() && !full_path.starts_with(&sess.sysroot) { + return false; + } + } + true +} + /// Whether we link to our own CRT objects instead of relying on gcc to pull them. /// We only provide such support for a very limited number of targets. fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool { - if let Some(self_contained) = sess.opts.debugging_opts.link_self_contained { + if let Some(self_contained) = sess.opts.cg.link_self_contained { return self_contained; } @@ -1298,10 +1241,10 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool { // based on host and linker path, for example. // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237). Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)), - // FIXME: Find some heuristic for "native mingw toolchain is available", - // likely based on `get_crt_libs_path` (https://github.com/rust-lang/rust/pull/67429). Some(CrtObjectsFallback::Mingw) => { - sess.host == sess.target.target && sess.target.target.target_vendor != "uwp" + sess.host == sess.target.target + && sess.target.target.target_vendor != "uwp" + && detect_self_contained_mingw(&sess) } // FIXME: Figure out cases in which WASM needs to link with a native toolchain. Some(CrtObjectsFallback::Wasm) => true, @@ -1498,16 +1441,6 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<' /// Add sysroot and other globally set directories to the directory search list. fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: bool) { - // Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details. - if sess.opts.debugging_opts.link_self_contained.is_none() - && cfg!(windows) - && sess.target.target.llvm_target.contains("windows-gnu") - { - if let Some(compiler_libs_path) = get_crt_libs_path(sess) { - cmd.include_path(&compiler_libs_path); - } - } - // The default library location, we need this to find the runtime. // The location of crates will be determined as needed. let lib_path = sess.target_filesearch(PathKind::All).get_lib_path(); @@ -1668,7 +1601,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // FIXME: Order dependent, applies to the following objects. Where should it be placed? // Try to strip as much out of the generated object by removing unused // sections if possible. See more comments in linker.rs - if sess.opts.cg.link_dead_code != Some(true) { + if !sess.link_dead_code() { let keep_metadata = crate_type == CrateType::Dylib; cmd.gc_sections(keep_metadata); } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 0ddf8bd316f..0ddf8bd316f 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs diff --git a/src/librustc_codegen_ssa/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index 0d7f4447696..0d7f4447696 100644 --- a/src/librustc_codegen_ssa/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs diff --git a/src/librustc_codegen_ssa/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs index 20ca503d43f..20ca503d43f 100644 --- a/src/librustc_codegen_ssa/back/mod.rs +++ b/compiler/rustc_codegen_ssa/src/back/mod.rs diff --git a/src/librustc_codegen_ssa/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs index 005d2efdd3b..005d2efdd3b 100644 --- a/src/librustc_codegen_ssa/back/rpath.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs diff --git a/src/librustc_codegen_ssa/back/rpath/tests.rs b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs index 35836ae719b..35836ae719b 100644 --- a/src/librustc_codegen_ssa/back/rpath/tests.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 51cc1ada432..51cc1ada432 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs diff --git a/src/librustc_codegen_ssa/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7d69bb983dd..7d69bb983dd 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs diff --git a/src/librustc_codegen_ssa/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 77c12c410d5..e0b649d91c7 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -38,7 +38,7 @@ use rustc_middle::middle::cstore::EncodedMetadata; use rustc_middle::middle::cstore::{self, LinkagePreference}; use rustc_middle::middle::lang_items; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; -use rustc_middle::ty::layout::{self, HasTyCtxt, TyAndLayout}; +use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -48,7 +48,7 @@ use rustc_session::utils::NativeLibKind; use rustc_session::Session; use rustc_span::Span; use rustc_symbol_mangling::test as symbol_names_test; -use rustc_target::abi::{Abi, Align, LayoutOf, Scalar, VariantIdx}; +use rustc_target::abi::{Align, LayoutOf, VariantIdx}; use std::cmp; use std::ops::{Deref, DerefMut}; @@ -330,35 +330,6 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { sess.target.target.options.is_like_msvc } -pub fn from_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - bx: &mut Bx, - val: Bx::Value, -) -> Bx::Value { - if bx.cx().val_ty(val) == bx.cx().type_i1() { bx.zext(val, bx.cx().type_i8()) } else { val } -} - -pub fn to_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - bx: &mut Bx, - val: Bx::Value, - layout: layout::TyAndLayout<'_>, -) -> Bx::Value { - if let Abi::Scalar(ref scalar) = layout.abi { - return to_immediate_scalar(bx, val, scalar); - } - val -} - -pub fn to_immediate_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - bx: &mut Bx, - val: Bx::Value, - scalar: &Scalar, -) -> Bx::Value { - if scalar.is_bool() { - return bx.trunc(val, bx.cx().type_i1()); - } - val -} - pub fn memcpy_ty<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, dst: Bx::Value, diff --git a/src/librustc_codegen_ssa/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index e04ed531bbf..e04ed531bbf 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs diff --git a/src/librustc_codegen_ssa/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs index a266d179a42..a266d179a42 100644 --- a/src/librustc_codegen_ssa/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs diff --git a/src/librustc_codegen_ssa/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 814e43c5fa5..814e43c5fa5 100644 --- a/src/librustc_codegen_ssa/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs diff --git a/src/librustc_codegen_ssa/coverageinfo/mod.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/mod.rs index 569fd3f1a51..569fd3f1a51 100644 --- a/src/librustc_codegen_ssa/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/mod.rs diff --git a/src/librustc_codegen_ssa/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs index d1a0cf78d6a..d1a0cf78d6a 100644 --- a/src/librustc_codegen_ssa/debuginfo/mod.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index fb8f5a62989..fb8f5a62989 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs diff --git a/src/librustc_codegen_ssa/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs index 5b086bc43ff..5b086bc43ff 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/compiler/rustc_codegen_ssa/src/glue.rs diff --git a/src/librustc_codegen_ssa/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 73e33369175..73e33369175 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs diff --git a/src/librustc_codegen_ssa/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index bcc19c6a44b..bcc19c6a44b 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 2e386c1e594..2e386c1e594 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs diff --git a/src/librustc_codegen_ssa/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 8048a569f79..6eb80157239 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1143,7 +1143,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } // We store bools as `i8` so we need to truncate to `i1`. - llval = base::to_immediate(bx, llval, arg.layout); + llval = bx.to_immediate(llval, arg.layout); } } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 4943e279c7e..4943e279c7e 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs diff --git a/src/librustc_codegen_ssa/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index a2ad27b925c..a2ad27b925c 100644 --- a/src/librustc_codegen_ssa/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d8a530d98fa..d8a530d98fa 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 26e6c354702..26e6c354702 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 937c7457c63..bbd004be875 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -147,8 +147,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", self, llty); // Reconstruct the immediate aggregate. let mut llpair = bx.cx().const_undef(llty); - let imm_a = base::from_immediate(bx, a); - let imm_b = base::from_immediate(bx, b); + let imm_a = bx.from_immediate(a); + let imm_b = bx.from_immediate(b); llpair = bx.insert_value(llpair, imm_a, 0); llpair = bx.insert_value(llpair, imm_b, 1); llpair @@ -168,9 +168,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { // Deconstruct the immediate aggregate. let a_llval = bx.extract_value(llval, 0); - let a_llval = base::to_immediate_scalar(bx, a_llval, a); + let a_llval = bx.to_immediate_scalar(a_llval, a); let b_llval = bx.extract_value(llval, 1); - let b_llval = base::to_immediate_scalar(bx, b_llval, b); + let b_llval = bx.to_immediate_scalar(b_llval, b); OperandValue::Pair(a_llval, b_llval) } else { OperandValue::Immediate(llval) @@ -220,29 +220,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { _ => bug!("OperandRef::extract_field({:?}): not applicable", self), }; - // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - // Bools in union fields needs to be truncated. - let to_immediate_or_cast = |bx: &mut Bx, val, ty| { - if ty == bx.cx().type_i1() { bx.trunc(val, ty) } else { bx.bitcast(val, ty) } - }; - - match val { - OperandValue::Immediate(ref mut llval) => { - *llval = to_immediate_or_cast(bx, *llval, bx.cx().immediate_backend_type(field)); + match (&mut val, &field.abi) { + (OperandValue::Immediate(llval), _) => { + // Bools in union fields needs to be truncated. + *llval = bx.to_immediate(*llval, field); + // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. + *llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field)); } - OperandValue::Pair(ref mut a, ref mut b) => { - *a = to_immediate_or_cast( - bx, - *a, - bx.cx().scalar_pair_element_backend_type(field, 0, true), - ); - *b = to_immediate_or_cast( - bx, - *b, - bx.cx().scalar_pair_element_backend_type(field, 1, true), - ); + (OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => { + // Bools in union fields needs to be truncated. + *a = bx.to_immediate_scalar(*a, a_abi); + *b = bx.to_immediate_scalar(*b, b_abi); + // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. + *a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true)); + *b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true)); } - OperandValue::Ref(..) => bug!(), + (OperandValue::Pair(..), _) => bug!(), + (OperandValue::Ref(..), _) => bug!(), } OperandRef { val, layout: field } @@ -302,7 +296,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { bug!("cannot directly store unsized values"); } OperandValue::Immediate(s) => { - let val = base::from_immediate(bx, s); + let val = bx.from_immediate(s); bx.store_with_flags(val, dest.llval, dest.align, flags); } OperandValue::Pair(a, b) => { @@ -313,12 +307,12 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi); let llptr = bx.struct_gep(dest.llval, 0); - let val = base::from_immediate(bx, a); + let val = bx.from_immediate(a); let align = dest.align; bx.store_with_flags(val, llptr, align, flags); let llptr = bx.struct_gep(dest.llval, 1); - let val = base::from_immediate(bx, b); + let val = bx.from_immediate(b); let align = dest.align.restrict_for_offset(b_offset); bx.store_with_flags(val, llptr, align, flags); } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 05656774f0e..05656774f0e 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 71f924df119..c64fc9bfcf0 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -98,7 +98,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } // Use llvm.memset.p0i8.* to initialize byte arrays - let v = base::from_immediate(&mut bx, v); + let v = bx.from_immediate(v); if bx.cx().val_ty(v) == bx.cx().type_i8() { bx.memset(start, v, size, dest.align, MemFlags::empty()); return bx; @@ -327,13 +327,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if er.end != er.start && scalar.valid_range.end() > scalar.valid_range.start() { - // We want `table[e as usize]` to not + // We want `table[e as usize ± k]` to not // have bound checks, and this is the most - // convenient place to put the `assume`. - let ll_t_in_const = + // convenient place to put the `assume`s. + if *scalar.valid_range.start() > 0 { + let enum_value_lower_bound = bx + .cx() + .const_uint_big(ll_t_in, *scalar.valid_range.start()); + let cmp_start = bx.icmp( + IntPredicate::IntUGE, + llval, + enum_value_lower_bound, + ); + bx.assume(cmp_start); + } + + let enum_value_upper_bound = bx.cx().const_uint_big(ll_t_in, *scalar.valid_range.end()); - let cmp = bx.icmp(IntPredicate::IntULE, llval, ll_t_in_const); - bx.assume(cmp); + let cmp_end = bx.icmp( + IntPredicate::IntULE, + llval, + enum_value_upper_bound, + ); + bx.assume(cmp_end); } } } diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 6f74ba77d4c..6f74ba77d4c 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs diff --git a/src/librustc_codegen_ssa/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index fc65149937f..607b5459673 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -21,7 +21,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) { debug!( "BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), + self, self.to_raw_string(), cx.codegen_unit().name() ); @@ -45,7 +45,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { debug!( "END IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), + self, self.to_raw_string(), cx.codegen_unit().name() ); @@ -59,7 +59,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { ) { debug!( "BEGIN PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), + self, self.to_raw_string(), cx.codegen_unit().name() ); @@ -80,7 +80,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { debug!( "END PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), + self, self.to_raw_string(), cx.codegen_unit().name() ); diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/compiler/rustc_codegen_ssa/src/traits/abi.rs index dd8495850bd..dd8495850bd 100644 --- a/src/librustc_codegen_ssa/traits/abi.rs +++ b/compiler/rustc_codegen_ssa/src/traits/abi.rs diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 69931935c49..69931935c49 100644 --- a/src/librustc_codegen_ssa/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 3522ea01153..3522ea01153 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 5ffc83c5f99..5142922260a 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -13,9 +13,9 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; use crate::MemFlags; -use rustc_middle::ty::layout::HasParamEnv; +use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; use rustc_middle::ty::Ty; -use rustc_target::abi::{Align, Size}; +use rustc_target::abi::{Abi, Align, Scalar, Size}; use rustc_target::spec::HasTargetSpec; use std::iter::TrustedLen; @@ -115,6 +115,16 @@ pub trait BuilderMethods<'a, 'tcx>: rhs: Self::Value, ) -> (Self::Value, Self::Value); + fn from_immediate(&mut self, val: Self::Value) -> Self::Value; + fn to_immediate(&mut self, val: Self::Value, layout: TyAndLayout<'_>) -> Self::Value { + if let Abi::Scalar(ref scalar) = layout.abi { + self.to_immediate_scalar(val, scalar) + } else { + val + } + } + fn to_immediate_scalar(&mut self, val: Self::Value, scalar: &Scalar) -> Self::Value; + fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value; fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value; fn array_alloca(&mut self, ty: Self::Type, len: Self::Value, align: Align) -> Self::Value; diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 6b58dea794b..6b58dea794b 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs diff --git a/src/librustc_codegen_ssa/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index b74e4e45901..b74e4e45901 100644 --- a/src/librustc_codegen_ssa/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index 1ee0f489ffc..1ee0f489ffc 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/compiler/rustc_codegen_ssa/src/traits/declare.rs index 690aacd2056..690aacd2056 100644 --- a/src/librustc_codegen_ssa/traits/declare.rs +++ b/compiler/rustc_codegen_ssa/src/traits/declare.rs diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 9d48e233de6..9d48e233de6 100644 --- a/src/librustc_codegen_ssa/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index fc57a9a80b2..fc57a9a80b2 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index 0ac519dd0b1..0ac519dd0b1 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs index 817fc02d166..817fc02d166 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 726d948cfd4..726d948cfd4 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs diff --git a/src/librustc_codegen_ssa/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 27d52e9b9c5..27d52e9b9c5 100644 --- a/src/librustc_codegen_ssa/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs diff --git a/src/librustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 988bb733f9f..fcae9b936ed 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -5,8 +5,6 @@ version = "0.0.0" edition = "2018" [lib] -name = "rustc_data_structures" -path = "lib.rs" doctest = false [dependencies] @@ -14,11 +12,9 @@ ena = "0.14" indexmap = "1.5.1" tracing = "0.1" jobserver_crate = { version = "0.1.13", package = "jobserver" } -lazy_static = "1" -once_cell = { version = "1", features = ["parking_lot"] } -rustc_serialize = { path = "../librustc_serialize" } -rustc_macros = { path = "../librustc_macros" } -rustc_graphviz = { path = "../librustc_graphviz" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_macros = { path = "../rustc_macros" } +rustc_graphviz = { path = "../rustc_graphviz" } cfg-if = "0.1.2" crossbeam-utils = { version = "0.7", features = ["nightly"] } stable_deref_trait = "1.0.0" @@ -26,7 +22,7 @@ rayon = { version = "0.3.0", package = "rustc-rayon" } rayon-core = { version = "0.3.0", package = "rustc-rayon-core" } rustc-hash = "1.1.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_index = { path = "../librustc_index", package = "rustc_index" } +rustc_index = { path = "../rustc_index", package = "rustc_index" } bitflags = "1.2.1" measureme = "0.7.1" libc = "0.2" diff --git a/src/librustc_data_structures/atomic_ref.rs b/compiler/rustc_data_structures/src/atomic_ref.rs index eeb1b309257..eeb1b309257 100644 --- a/src/librustc_data_structures/atomic_ref.rs +++ b/compiler/rustc_data_structures/src/atomic_ref.rs diff --git a/src/librustc_data_structures/base_n.rs b/compiler/rustc_data_structures/src/base_n.rs index 3c7bea27124..3c7bea27124 100644 --- a/src/librustc_data_structures/base_n.rs +++ b/compiler/rustc_data_structures/src/base_n.rs diff --git a/src/librustc_data_structures/base_n/tests.rs b/compiler/rustc_data_structures/src/base_n/tests.rs index b68ef1eb7f4..b68ef1eb7f4 100644 --- a/src/librustc_data_structures/base_n/tests.rs +++ b/compiler/rustc_data_structures/src/base_n/tests.rs diff --git a/src/librustc_data_structures/binary_search_util/mod.rs b/compiler/rustc_data_structures/src/binary_search_util/mod.rs index ede5757a479..ede5757a479 100644 --- a/src/librustc_data_structures/binary_search_util/mod.rs +++ b/compiler/rustc_data_structures/src/binary_search_util/mod.rs diff --git a/src/librustc_data_structures/binary_search_util/tests.rs b/compiler/rustc_data_structures/src/binary_search_util/tests.rs index d74febb5c0f..d74febb5c0f 100644 --- a/src/librustc_data_structures/binary_search_util/tests.rs +++ b/compiler/rustc_data_structures/src/binary_search_util/tests.rs diff --git a/src/librustc_data_structures/box_region.rs b/compiler/rustc_data_structures/src/box_region.rs index eb6f4e8213e..eb6f4e8213e 100644 --- a/src/librustc_data_structures/box_region.rs +++ b/compiler/rustc_data_structures/src/box_region.rs diff --git a/src/librustc_data_structures/captures.rs b/compiler/rustc_data_structures/src/captures.rs index 26b90ebfd5f..26b90ebfd5f 100644 --- a/src/librustc_data_structures/captures.rs +++ b/compiler/rustc_data_structures/src/captures.rs diff --git a/src/librustc_data_structures/const_cstr.rs b/compiler/rustc_data_structures/src/const_cstr.rs index 1ebcb87818e..1ebcb87818e 100644 --- a/src/librustc_data_structures/const_cstr.rs +++ b/compiler/rustc_data_structures/src/const_cstr.rs diff --git a/src/librustc_data_structures/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index f8d631ce01e..aba0bbbac80 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -3,9 +3,10 @@ use rustc_serialize::{ opaque::{self, EncodeResult}, Decodable, Encodable, }; +use std::hash::{Hash, Hasher}; use std::mem; -#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy)] pub struct Fingerprint(u64, u64); impl Fingerprint { @@ -76,6 +77,33 @@ impl ::std::fmt::Display for Fingerprint { } } +impl Hash for Fingerprint { + #[inline] + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_fingerprint(self); + } +} + +trait FingerprintHasher { + fn write_fingerprint(&mut self, fingerprint: &Fingerprint); +} + +impl<H: Hasher> FingerprintHasher for H { + #[inline] + default fn write_fingerprint(&mut self, fingerprint: &Fingerprint) { + self.write_u64(fingerprint.0); + self.write_u64(fingerprint.1); + } +} + +impl FingerprintHasher for crate::unhash::Unhasher { + #[inline] + fn write_fingerprint(&mut self, fingerprint: &Fingerprint) { + // `Unhasher` only wants a single `u64` + self.write_u64(fingerprint.0); + } +} + impl stable_hasher::StableHasherResult for Fingerprint { #[inline] fn finish(hasher: stable_hasher::StableHasher) -> Self { diff --git a/src/librustc_data_structures/flock.rs b/compiler/rustc_data_structures/src/flock.rs index 9383be474fd..9383be474fd 100644 --- a/src/librustc_data_structures/flock.rs +++ b/compiler/rustc_data_structures/src/flock.rs diff --git a/src/librustc_data_structures/frozen.rs b/compiler/rustc_data_structures/src/frozen.rs index 2daf5b04141..2daf5b04141 100644 --- a/src/librustc_data_structures/frozen.rs +++ b/compiler/rustc_data_structures/src/frozen.rs diff --git a/src/librustc_data_structures/fx.rs b/compiler/rustc_data_structures/src/fx.rs index bbeb193dba3..bbeb193dba3 100644 --- a/src/librustc_data_structures/fx.rs +++ b/compiler/rustc_data_structures/src/fx.rs diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 438a0d0c6ff..438a0d0c6ff 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs diff --git a/src/librustc_data_structures/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs index 1160df5186b..1160df5186b 100644 --- a/src/librustc_data_structures/graph/dominators/tests.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs index 1aa7ac024d9..1aa7ac024d9 100644 --- a/src/librustc_data_structures/graph/implementation/mod.rs +++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs diff --git a/src/librustc_data_structures/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/implementation/tests.rs index e4e4d0d44ba..e4e4d0d44ba 100644 --- a/src/librustc_data_structures/graph/implementation/tests.rs +++ b/compiler/rustc_data_structures/src/graph/implementation/tests.rs diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 64ff6130ddf..64ff6130ddf 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs diff --git a/src/librustc_data_structures/graph/iterate/tests.rs b/compiler/rustc_data_structures/src/graph/iterate/tests.rs index 0e038e88b22..0e038e88b22 100644 --- a/src/librustc_data_structures/graph/iterate/tests.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/tests.rs diff --git a/src/librustc_data_structures/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index e0903e43241..e0903e43241 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs diff --git a/src/librustc_data_structures/graph/reference.rs b/compiler/rustc_data_structures/src/graph/reference.rs index c259fe56c15..c259fe56c15 100644 --- a/src/librustc_data_structures/graph/reference.rs +++ b/compiler/rustc_data_structures/src/graph/reference.rs diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 2db8e466e11..2db8e466e11 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs diff --git a/src/librustc_data_structures/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs index 1d5f46ebab1..1d5f46ebab1 100644 --- a/src/librustc_data_structures/graph/scc/tests.rs +++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs diff --git a/src/librustc_data_structures/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs index 7f4ef906b36..7f4ef906b36 100644 --- a/src/librustc_data_structures/graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/tests.rs diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs index 064467174ca..064467174ca 100644 --- a/src/librustc_data_structures/graph/vec_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs diff --git a/src/librustc_data_structures/graph/vec_graph/tests.rs b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs index c8f97926717..c8f97926717 100644 --- a/src/librustc_data_structures/graph/vec_graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs new file mode 100644 index 00000000000..41605afb44e --- /dev/null +++ b/compiler/rustc_data_structures/src/jobserver.rs @@ -0,0 +1,40 @@ +pub use jobserver_crate::Client; +use std::lazy::SyncLazy; + +// We can only call `from_env` once per process + +// Note that this is unsafe because it may misinterpret file descriptors +// on Unix as jobserver file descriptors. We hopefully execute this near +// the beginning of the process though to ensure we don't get false +// positives, or in other words we try to execute this before we open +// any file descriptors ourselves. +// +// Pick a "reasonable maximum" if we don't otherwise have +// a jobserver in our environment, capping out at 32 so we +// don't take everything down by hogging the process run queue. +// The fixed number is used to have deterministic compilation +// across machines. +// +// Also note that we stick this in a global because there could be +// multiple rustc instances in this process, and the jobserver is +// per-process. +static GLOBAL_CLIENT: SyncLazy<Client> = SyncLazy::new(|| unsafe { + Client::from_env().unwrap_or_else(|| { + let client = Client::new(32).expect("failed to create jobserver"); + // Acquire a token for the main thread which we can release later + client.acquire_raw().ok(); + client + }) +}); + +pub fn client() -> Client { + GLOBAL_CLIENT.clone() +} + +pub fn acquire_thread() { + GLOBAL_CLIENT.acquire_raw().ok(); +} + +pub fn release_thread() { + GLOBAL_CLIENT.release_raw().ok(); +} diff --git a/src/librustc_data_structures/lib.rs b/compiler/rustc_data_structures/src/lib.rs index af4a7bd1881..de4e7a13424 100644 --- a/src/librustc_data_structures/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -26,6 +26,7 @@ #![feature(extend_one)] #![feature(const_panic)] #![feature(const_generics)] +#![feature(once_cell)] #![allow(rustc::default_hash_types)] #[macro_use] @@ -102,6 +103,7 @@ pub use atomic_ref::AtomicRef; pub mod frozen; pub mod tagged_ptr; pub mod temp_dir; +pub mod unhash; pub struct OnDrop<F: Fn()>(pub F); diff --git a/src/librustc_data_structures/macros.rs b/compiler/rustc_data_structures/src/macros.rs index 67fbe3058cd..67fbe3058cd 100644 --- a/src/librustc_data_structures/macros.rs +++ b/compiler/rustc_data_structures/src/macros.rs diff --git a/src/librustc_data_structures/map_in_place.rs b/compiler/rustc_data_structures/src/map_in_place.rs index 5dd9fc6e8bc..5dd9fc6e8bc 100644 --- a/src/librustc_data_structures/map_in_place.rs +++ b/compiler/rustc_data_structures/src/map_in_place.rs diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs index 3a268e4b4f4..3a268e4b4f4 100644 --- a/src/librustc_data_structures/obligation_forest/graphviz.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index 7cf5202d919..7cf5202d919 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs diff --git a/src/librustc_data_structures/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs index 01652465eea..01652465eea 100644 --- a/src/librustc_data_structures/obligation_forest/tests.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs diff --git a/src/librustc_data_structures/owning_ref/LICENSE b/compiler/rustc_data_structures/src/owning_ref/LICENSE index dff72d1e432..dff72d1e432 100644 --- a/src/librustc_data_structures/owning_ref/LICENSE +++ b/compiler/rustc_data_structures/src/owning_ref/LICENSE diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/compiler/rustc_data_structures/src/owning_ref/mod.rs index ad4b79de236..ad4b79de236 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/compiler/rustc_data_structures/src/owning_ref/mod.rs diff --git a/src/librustc_data_structures/owning_ref/tests.rs b/compiler/rustc_data_structures/src/owning_ref/tests.rs index 7b8179e90bd..7b8179e90bd 100644 --- a/src/librustc_data_structures/owning_ref/tests.rs +++ b/compiler/rustc_data_structures/src/owning_ref/tests.rs diff --git a/src/librustc_data_structures/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 07d16c6483e..07d16c6483e 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs diff --git a/src/librustc_data_structures/ptr_key.rs b/compiler/rustc_data_structures/src/ptr_key.rs index 440ccb05d86..440ccb05d86 100644 --- a/src/librustc_data_structures/ptr_key.rs +++ b/compiler/rustc_data_structures/src/ptr_key.rs diff --git a/src/librustc_data_structures/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 485719c5175..485719c5175 100644 --- a/src/librustc_data_structures/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs diff --git a/src/librustc_data_structures/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index beb28dd0720..beb28dd0720 100644 --- a/src/librustc_data_structures/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs diff --git a/src/librustc_data_structures/sip128/tests.rs b/compiler/rustc_data_structures/src/sip128/tests.rs index 80b7fc74756..80b7fc74756 100644 --- a/src/librustc_data_structures/sip128/tests.rs +++ b/compiler/rustc_data_structures/src/sip128/tests.rs diff --git a/src/librustc_data_structures/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs index 4a089398ce6..4a089398ce6 100644 --- a/src/librustc_data_structures/small_c_str.rs +++ b/compiler/rustc_data_structures/src/small_c_str.rs diff --git a/src/librustc_data_structures/small_c_str/tests.rs b/compiler/rustc_data_structures/src/small_c_str/tests.rs index 47277604b2b..47277604b2b 100644 --- a/src/librustc_data_structures/small_c_str/tests.rs +++ b/compiler/rustc_data_structures/src/small_c_str/tests.rs diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/compiler/rustc_data_structures/src/snapshot_map/mod.rs index b4cc85293f7..b4cc85293f7 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/compiler/rustc_data_structures/src/snapshot_map/mod.rs diff --git a/src/librustc_data_structures/snapshot_map/tests.rs b/compiler/rustc_data_structures/src/snapshot_map/tests.rs index 72ca53c2be9..72ca53c2be9 100644 --- a/src/librustc_data_structures/snapshot_map/tests.rs +++ b/compiler/rustc_data_structures/src/snapshot_map/tests.rs diff --git a/src/librustc_data_structures/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 856eb73e629..856eb73e629 100644 --- a/src/librustc_data_structures/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs diff --git a/src/librustc_data_structures/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index 2bb421a47ef..2bb421a47ef 100644 --- a/src/librustc_data_structures/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs diff --git a/src/librustc_data_structures/sorted_map/tests.rs b/compiler/rustc_data_structures/src/sorted_map/tests.rs index 7d91e1fdcef..7d91e1fdcef 100644 --- a/src/librustc_data_structures/sorted_map/tests.rs +++ b/compiler/rustc_data_structures/src/sorted_map/tests.rs diff --git a/src/librustc_data_structures/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index c1c79b174f4..c1c79b174f4 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs diff --git a/src/librustc_data_structures/stable_map.rs b/compiler/rustc_data_structures/src/stable_map.rs index 670452d0d8c..670452d0d8c 100644 --- a/src/librustc_data_structures/stable_map.rs +++ b/compiler/rustc_data_structures/src/stable_map.rs diff --git a/src/librustc_data_structures/stable_set.rs b/compiler/rustc_data_structures/src/stable_set.rs index c7ca74f5fbd..c7ca74f5fbd 100644 --- a/src/librustc_data_structures/stable_set.rs +++ b/compiler/rustc_data_structures/src/stable_set.rs diff --git a/src/librustc_data_structures/stack.rs b/compiler/rustc_data_structures/src/stack.rs index a4964b7aa0c..a4964b7aa0c 100644 --- a/src/librustc_data_structures/stack.rs +++ b/compiler/rustc_data_structures/src/stack.rs diff --git a/src/librustc_data_structures/svh.rs b/compiler/rustc_data_structures/src/svh.rs index 02103de2e8d..02103de2e8d 100644 --- a/src/librustc_data_structures/svh.rs +++ b/compiler/rustc_data_structures/src/svh.rs diff --git a/src/librustc_data_structures/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 53d831749ce..d22f3adfb01 100644 --- a/src/librustc_data_structures/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -229,7 +229,7 @@ cfg_if! { pub use std::cell::RefMut as LockGuard; pub use std::cell::RefMut as MappedLockGuard; - pub use once_cell::unsync::OnceCell; + pub use std::lazy::OnceCell; use std::cell::RefCell as InnerRwLock; use std::cell::RefCell as InnerLock; @@ -314,7 +314,7 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use once_cell::sync::OnceCell; + pub use std::lazy::SyncOnceCell as OnceCell; pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; diff --git a/src/librustc_data_structures/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs index e3839d19365..e3839d19365 100644 --- a/src/librustc_data_structures/tagged_ptr.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr.rs diff --git a/src/librustc_data_structures/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs index d39d146db31..d39d146db31 100644 --- a/src/librustc_data_structures/tagged_ptr/copy.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs diff --git a/src/librustc_data_structures/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs index 63f64beae5a..63f64beae5a 100644 --- a/src/librustc_data_structures/tagged_ptr/drop.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs diff --git a/src/librustc_data_structures/temp_dir.rs b/compiler/rustc_data_structures/src/temp_dir.rs index 0d9b3e3ca25..0d9b3e3ca25 100644 --- a/src/librustc_data_structures/temp_dir.rs +++ b/compiler/rustc_data_structures/src/temp_dir.rs diff --git a/src/librustc_data_structures/thin_vec.rs b/compiler/rustc_data_structures/src/thin_vec.rs index 4d673fd5cf9..4d673fd5cf9 100644 --- a/src/librustc_data_structures/thin_vec.rs +++ b/compiler/rustc_data_structures/src/thin_vec.rs diff --git a/src/librustc_data_structures/tiny_list.rs b/compiler/rustc_data_structures/src/tiny_list.rs index e94a0c6eb59..e94a0c6eb59 100644 --- a/src/librustc_data_structures/tiny_list.rs +++ b/compiler/rustc_data_structures/src/tiny_list.rs diff --git a/src/librustc_data_structures/tiny_list/tests.rs b/compiler/rustc_data_structures/src/tiny_list/tests.rs index a8ae2bc8727..a8ae2bc8727 100644 --- a/src/librustc_data_structures/tiny_list/tests.rs +++ b/compiler/rustc_data_structures/src/tiny_list/tests.rs diff --git a/src/librustc_data_structures/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs index fe60a99dde0..fe60a99dde0 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/compiler/rustc_data_structures/src/transitive_relation.rs diff --git a/src/librustc_data_structures/transitive_relation/tests.rs b/compiler/rustc_data_structures/src/transitive_relation/tests.rs index ca90ba176ae..ca90ba176ae 100644 --- a/src/librustc_data_structures/transitive_relation/tests.rs +++ b/compiler/rustc_data_structures/src/transitive_relation/tests.rs diff --git a/compiler/rustc_data_structures/src/unhash.rs b/compiler/rustc_data_structures/src/unhash.rs new file mode 100644 index 00000000000..48e21a9dab1 --- /dev/null +++ b/compiler/rustc_data_structures/src/unhash.rs @@ -0,0 +1,29 @@ +use std::collections::{HashMap, HashSet}; +use std::hash::{BuildHasherDefault, Hasher}; + +pub type UnhashMap<K, V> = HashMap<K, V, BuildHasherDefault<Unhasher>>; +pub type UnhashSet<V> = HashSet<V, BuildHasherDefault<Unhasher>>; + +/// This no-op hasher expects only a single `write_u64` call. It's intended for +/// map keys that already have hash-like quality, like `Fingerprint`. +#[derive(Default)] +pub struct Unhasher { + value: u64, +} + +impl Hasher for Unhasher { + #[inline] + fn finish(&self) -> u64 { + self.value + } + + fn write(&mut self, _bytes: &[u8]) { + unimplemented!("use write_u64"); + } + + #[inline] + fn write_u64(&mut self, value: u64) { + debug_assert_eq!(0, self.value, "Unhasher doesn't mix values!"); + self.value = value; + } +} diff --git a/src/librustc_data_structures/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs index 1cf030d852e..1cf030d852e 100644 --- a/src/librustc_data_structures/vec_linked_list.rs +++ b/compiler/rustc_data_structures/src/vec_linked_list.rs diff --git a/src/librustc_data_structures/work_queue.rs b/compiler/rustc_data_structures/src/work_queue.rs index 0c848eb144d..0c848eb144d 100644 --- a/src/librustc_data_structures/work_queue.rs +++ b/compiler/rustc_data_structures/src/work_queue.rs diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml new file mode 100644 index 00000000000..0d9dcb262b2 --- /dev/null +++ b/compiler/rustc_driver/Cargo.toml @@ -0,0 +1,40 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_driver" +version = "0.0.0" +edition = "2018" + +[lib] +crate-type = ["dylib"] + +[dependencies] +libc = "0.2" +tracing = { version = "0.1.18", features = ["release_max_level_info"] } +tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } +rustc_middle = { path = "../rustc_middle" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_target = { path = "../rustc_target" } +rustc_lint = { path = "../rustc_lint" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_metadata = { path = "../rustc_metadata" } +rustc_mir = { path = "../rustc_mir" } +rustc_parse = { path = "../rustc_parse" } +rustc_plugin_impl = { path = "../rustc_plugin_impl" } +rustc_save_analysis = { path = "../rustc_save_analysis" } +rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } +rustc_session = { path = "../rustc_session" } +rustc_error_codes = { path = "../rustc_error_codes" } +rustc_interface = { path = "../rustc_interface" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } + +[features] +llvm = ['rustc_interface/llvm'] diff --git a/src/librustc_driver/README.md b/compiler/rustc_driver/README.md index 37dc7f6ba5f..37dc7f6ba5f 100644 --- a/src/librustc_driver/README.md +++ b/compiler/rustc_driver/README.md diff --git a/src/librustc_driver/args.rs b/compiler/rustc_driver/src/args.rs index 5686819c61b..5686819c61b 100644 --- a/src/librustc_driver/args.rs +++ b/compiler/rustc_driver/src/args.rs diff --git a/src/librustc_driver/lib.rs b/compiler/rustc_driver/src/lib.rs index 09f5b22cc63..c277e314d0e 100644 --- a/src/librustc_driver/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -6,12 +6,11 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(nll)] +#![feature(once_cell)] #![recursion_limit = "256"] #[macro_use] extern crate tracing; -#[macro_use] -extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; @@ -48,6 +47,7 @@ use std::env; use std::ffi::OsString; use std::fs; use std::io::{self, Read, Write}; +use std::lazy::SyncLazy; use std::mem; use std::panic::{self, catch_unwind}; use std::path::PathBuf; @@ -1141,13 +1141,12 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { } } -lazy_static! { - static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = { +static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> = + SyncLazy::new(|| { let hook = panic::take_hook(); panic::set_hook(Box::new(|info| report_ice(info, BUG_REPORT_URL))); hook - }; -} + }); /// Prints the ICE message, including backtrace and query stack. /// @@ -1222,7 +1221,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { /// /// A custom rustc driver can skip calling this to set up a custom ICE hook. pub fn install_ice_hook() { - lazy_static::initialize(&DEFAULT_HOOK); + SyncLazy::force(&DEFAULT_HOOK); } /// This allows tools to enable rust logging without having to magically match rustc's diff --git a/src/librustc_driver/pretty.rs b/compiler/rustc_driver/src/pretty.rs index b0fbf1e03f5..b0fbf1e03f5 100644 --- a/src/librustc_driver/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs diff --git a/src/librustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml index 5def867ff11..b4c9cd94565 100644 --- a/src/librustc_error_codes/Cargo.toml +++ b/compiler/rustc_error_codes/Cargo.toml @@ -3,7 +3,3 @@ authors = ["The Rust Project Developers"] name = "rustc_error_codes" version = "0.0.0" edition = "2018" - -[lib] -name = "rustc_error_codes" -path = "lib.rs" diff --git a/src/librustc_error_codes/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 4e5e77f80c2..789a1fc35a6 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -454,6 +454,7 @@ E0768: include_str!("./error_codes/E0768.md"), E0769: include_str!("./error_codes/E0769.md"), E0770: include_str!("./error_codes/E0770.md"), E0771: include_str!("./error_codes/E0771.md"), +E0773: include_str!("./error_codes/E0773.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0001.md b/compiler/rustc_error_codes/src/error_codes/E0001.md index 90756780d15..90756780d15 100644 --- a/src/librustc_error_codes/error_codes/E0001.md +++ b/compiler/rustc_error_codes/src/error_codes/E0001.md diff --git a/src/librustc_error_codes/error_codes/E0002.md b/compiler/rustc_error_codes/src/error_codes/E0002.md index 5cb59da10e0..5cb59da10e0 100644 --- a/src/librustc_error_codes/error_codes/E0002.md +++ b/compiler/rustc_error_codes/src/error_codes/E0002.md diff --git a/src/librustc_error_codes/error_codes/E0004.md b/compiler/rustc_error_codes/src/error_codes/E0004.md index b79ef5fd8cb..b79ef5fd8cb 100644 --- a/src/librustc_error_codes/error_codes/E0004.md +++ b/compiler/rustc_error_codes/src/error_codes/E0004.md diff --git a/src/librustc_error_codes/error_codes/E0005.md b/compiler/rustc_error_codes/src/error_codes/E0005.md index e2e7db5082d..e2e7db5082d 100644 --- a/src/librustc_error_codes/error_codes/E0005.md +++ b/compiler/rustc_error_codes/src/error_codes/E0005.md diff --git a/src/librustc_error_codes/error_codes/E0007.md b/compiler/rustc_error_codes/src/error_codes/E0007.md index 2be7870d5ae..2be7870d5ae 100644 --- a/src/librustc_error_codes/error_codes/E0007.md +++ b/compiler/rustc_error_codes/src/error_codes/E0007.md diff --git a/src/librustc_error_codes/error_codes/E0009.md b/compiler/rustc_error_codes/src/error_codes/E0009.md index aaabba04349..aaabba04349 100644 --- a/src/librustc_error_codes/error_codes/E0009.md +++ b/compiler/rustc_error_codes/src/error_codes/E0009.md diff --git a/src/librustc_error_codes/error_codes/E0010.md b/compiler/rustc_error_codes/src/error_codes/E0010.md index 71c790e102f..71c790e102f 100644 --- a/src/librustc_error_codes/error_codes/E0010.md +++ b/compiler/rustc_error_codes/src/error_codes/E0010.md diff --git a/src/librustc_error_codes/error_codes/E0013.md b/compiler/rustc_error_codes/src/error_codes/E0013.md index 8de177590ec..8de177590ec 100644 --- a/src/librustc_error_codes/error_codes/E0013.md +++ b/compiler/rustc_error_codes/src/error_codes/E0013.md diff --git a/src/librustc_error_codes/error_codes/E0014.md b/compiler/rustc_error_codes/src/error_codes/E0014.md index 2c69957e9f6..2c69957e9f6 100644 --- a/src/librustc_error_codes/error_codes/E0014.md +++ b/compiler/rustc_error_codes/src/error_codes/E0014.md diff --git a/src/librustc_error_codes/error_codes/E0015.md b/compiler/rustc_error_codes/src/error_codes/E0015.md index 021a0219d13..021a0219d13 100644 --- a/src/librustc_error_codes/error_codes/E0015.md +++ b/compiler/rustc_error_codes/src/error_codes/E0015.md diff --git a/src/librustc_error_codes/error_codes/E0019.md b/compiler/rustc_error_codes/src/error_codes/E0019.md index 7832468a539..7832468a539 100644 --- a/src/librustc_error_codes/error_codes/E0019.md +++ b/compiler/rustc_error_codes/src/error_codes/E0019.md diff --git a/src/librustc_error_codes/error_codes/E0023.md b/compiler/rustc_error_codes/src/error_codes/E0023.md index c1d85705da3..c1d85705da3 100644 --- a/src/librustc_error_codes/error_codes/E0023.md +++ b/compiler/rustc_error_codes/src/error_codes/E0023.md diff --git a/src/librustc_error_codes/error_codes/E0025.md b/compiler/rustc_error_codes/src/error_codes/E0025.md index a85dc8c1978..a85dc8c1978 100644 --- a/src/librustc_error_codes/error_codes/E0025.md +++ b/compiler/rustc_error_codes/src/error_codes/E0025.md diff --git a/src/librustc_error_codes/error_codes/E0026.md b/compiler/rustc_error_codes/src/error_codes/E0026.md index 72c575aabb6..72c575aabb6 100644 --- a/src/librustc_error_codes/error_codes/E0026.md +++ b/compiler/rustc_error_codes/src/error_codes/E0026.md diff --git a/src/librustc_error_codes/error_codes/E0027.md b/compiler/rustc_error_codes/src/error_codes/E0027.md index a8b1340ca0c..a8b1340ca0c 100644 --- a/src/librustc_error_codes/error_codes/E0027.md +++ b/compiler/rustc_error_codes/src/error_codes/E0027.md diff --git a/src/librustc_error_codes/error_codes/E0029.md b/compiler/rustc_error_codes/src/error_codes/E0029.md index d12d85b9b4c..d12d85b9b4c 100644 --- a/src/librustc_error_codes/error_codes/E0029.md +++ b/compiler/rustc_error_codes/src/error_codes/E0029.md diff --git a/src/librustc_error_codes/error_codes/E0030.md b/compiler/rustc_error_codes/src/error_codes/E0030.md index 67d496da5e4..67d496da5e4 100644 --- a/src/librustc_error_codes/error_codes/E0030.md +++ b/compiler/rustc_error_codes/src/error_codes/E0030.md diff --git a/src/librustc_error_codes/error_codes/E0033.md b/compiler/rustc_error_codes/src/error_codes/E0033.md index 735a2d1f3fe..735a2d1f3fe 100644 --- a/src/librustc_error_codes/error_codes/E0033.md +++ b/compiler/rustc_error_codes/src/error_codes/E0033.md diff --git a/src/librustc_error_codes/error_codes/E0034.md b/compiler/rustc_error_codes/src/error_codes/E0034.md index 2a21f3441c6..2a21f3441c6 100644 --- a/src/librustc_error_codes/error_codes/E0034.md +++ b/compiler/rustc_error_codes/src/error_codes/E0034.md diff --git a/src/librustc_error_codes/error_codes/E0038.md b/compiler/rustc_error_codes/src/error_codes/E0038.md index b2cc2a2273a..b2cc2a2273a 100644 --- a/src/librustc_error_codes/error_codes/E0038.md +++ b/compiler/rustc_error_codes/src/error_codes/E0038.md diff --git a/src/librustc_error_codes/error_codes/E0040.md b/compiler/rustc_error_codes/src/error_codes/E0040.md index 1373f8340d8..1373f8340d8 100644 --- a/src/librustc_error_codes/error_codes/E0040.md +++ b/compiler/rustc_error_codes/src/error_codes/E0040.md diff --git a/src/librustc_error_codes/error_codes/E0044.md b/compiler/rustc_error_codes/src/error_codes/E0044.md index 635ff953290..635ff953290 100644 --- a/src/librustc_error_codes/error_codes/E0044.md +++ b/compiler/rustc_error_codes/src/error_codes/E0044.md diff --git a/src/librustc_error_codes/error_codes/E0045.md b/compiler/rustc_error_codes/src/error_codes/E0045.md index 143c693bf7c..143c693bf7c 100644 --- a/src/librustc_error_codes/error_codes/E0045.md +++ b/compiler/rustc_error_codes/src/error_codes/E0045.md diff --git a/src/librustc_error_codes/error_codes/E0046.md b/compiler/rustc_error_codes/src/error_codes/E0046.md index d8f95330c36..d8f95330c36 100644 --- a/src/librustc_error_codes/error_codes/E0046.md +++ b/compiler/rustc_error_codes/src/error_codes/E0046.md diff --git a/src/librustc_error_codes/error_codes/E0049.md b/compiler/rustc_error_codes/src/error_codes/E0049.md index a2034a3428b..a2034a3428b 100644 --- a/src/librustc_error_codes/error_codes/E0049.md +++ b/compiler/rustc_error_codes/src/error_codes/E0049.md diff --git a/src/librustc_error_codes/error_codes/E0050.md b/compiler/rustc_error_codes/src/error_codes/E0050.md index 7b84c480073..7b84c480073 100644 --- a/src/librustc_error_codes/error_codes/E0050.md +++ b/compiler/rustc_error_codes/src/error_codes/E0050.md diff --git a/src/librustc_error_codes/error_codes/E0053.md b/compiler/rustc_error_codes/src/error_codes/E0053.md index cb2a8638a29..cb2a8638a29 100644 --- a/src/librustc_error_codes/error_codes/E0053.md +++ b/compiler/rustc_error_codes/src/error_codes/E0053.md diff --git a/src/librustc_error_codes/error_codes/E0054.md b/compiler/rustc_error_codes/src/error_codes/E0054.md index c3eb375fbcc..c3eb375fbcc 100644 --- a/src/librustc_error_codes/error_codes/E0054.md +++ b/compiler/rustc_error_codes/src/error_codes/E0054.md diff --git a/src/librustc_error_codes/error_codes/E0055.md b/compiler/rustc_error_codes/src/error_codes/E0055.md index 223ba400029..223ba400029 100644 --- a/src/librustc_error_codes/error_codes/E0055.md +++ b/compiler/rustc_error_codes/src/error_codes/E0055.md diff --git a/src/librustc_error_codes/error_codes/E0057.md b/compiler/rustc_error_codes/src/error_codes/E0057.md index bb5e4b48d2d..bb5e4b48d2d 100644 --- a/src/librustc_error_codes/error_codes/E0057.md +++ b/compiler/rustc_error_codes/src/error_codes/E0057.md diff --git a/src/librustc_error_codes/error_codes/E0059.md b/compiler/rustc_error_codes/src/error_codes/E0059.md index b22edead25e..b22edead25e 100644 --- a/src/librustc_error_codes/error_codes/E0059.md +++ b/compiler/rustc_error_codes/src/error_codes/E0059.md diff --git a/src/librustc_error_codes/error_codes/E0060.md b/compiler/rustc_error_codes/src/error_codes/E0060.md index e6906d72367..e6906d72367 100644 --- a/src/librustc_error_codes/error_codes/E0060.md +++ b/compiler/rustc_error_codes/src/error_codes/E0060.md diff --git a/src/librustc_error_codes/error_codes/E0061.md b/compiler/rustc_error_codes/src/error_codes/E0061.md index 143251c13b0..143251c13b0 100644 --- a/src/librustc_error_codes/error_codes/E0061.md +++ b/compiler/rustc_error_codes/src/error_codes/E0061.md diff --git a/src/librustc_error_codes/error_codes/E0062.md b/compiler/rustc_error_codes/src/error_codes/E0062.md index 64fc027b885..64fc027b885 100644 --- a/src/librustc_error_codes/error_codes/E0062.md +++ b/compiler/rustc_error_codes/src/error_codes/E0062.md diff --git a/src/librustc_error_codes/error_codes/E0063.md b/compiler/rustc_error_codes/src/error_codes/E0063.md index 0e611deac42..0e611deac42 100644 --- a/src/librustc_error_codes/error_codes/E0063.md +++ b/compiler/rustc_error_codes/src/error_codes/E0063.md diff --git a/src/librustc_error_codes/error_codes/E0067.md b/compiler/rustc_error_codes/src/error_codes/E0067.md index 11041bb53ee..11041bb53ee 100644 --- a/src/librustc_error_codes/error_codes/E0067.md +++ b/compiler/rustc_error_codes/src/error_codes/E0067.md diff --git a/src/librustc_error_codes/error_codes/E0069.md b/compiler/rustc_error_codes/src/error_codes/E0069.md index 7367a5c0922..7367a5c0922 100644 --- a/src/librustc_error_codes/error_codes/E0069.md +++ b/compiler/rustc_error_codes/src/error_codes/E0069.md diff --git a/src/librustc_error_codes/error_codes/E0070.md b/compiler/rustc_error_codes/src/error_codes/E0070.md index 97522af3da8..97522af3da8 100644 --- a/src/librustc_error_codes/error_codes/E0070.md +++ b/compiler/rustc_error_codes/src/error_codes/E0070.md diff --git a/src/librustc_error_codes/error_codes/E0071.md b/compiler/rustc_error_codes/src/error_codes/E0071.md index bc2c03a0220..bc2c03a0220 100644 --- a/src/librustc_error_codes/error_codes/E0071.md +++ b/compiler/rustc_error_codes/src/error_codes/E0071.md diff --git a/src/librustc_error_codes/error_codes/E0072.md b/compiler/rustc_error_codes/src/error_codes/E0072.md index 8f7749abab1..8f7749abab1 100644 --- a/src/librustc_error_codes/error_codes/E0072.md +++ b/compiler/rustc_error_codes/src/error_codes/E0072.md diff --git a/src/librustc_error_codes/error_codes/E0073.md b/compiler/rustc_error_codes/src/error_codes/E0073.md index a5aea86ff2d..a5aea86ff2d 100644 --- a/src/librustc_error_codes/error_codes/E0073.md +++ b/compiler/rustc_error_codes/src/error_codes/E0073.md diff --git a/src/librustc_error_codes/error_codes/E0074.md b/compiler/rustc_error_codes/src/error_codes/E0074.md index e25dec7681b..e25dec7681b 100644 --- a/src/librustc_error_codes/error_codes/E0074.md +++ b/compiler/rustc_error_codes/src/error_codes/E0074.md diff --git a/src/librustc_error_codes/error_codes/E0075.md b/compiler/rustc_error_codes/src/error_codes/E0075.md index 969c1ee7131..969c1ee7131 100644 --- a/src/librustc_error_codes/error_codes/E0075.md +++ b/compiler/rustc_error_codes/src/error_codes/E0075.md diff --git a/src/librustc_error_codes/error_codes/E0076.md b/compiler/rustc_error_codes/src/error_codes/E0076.md index f293a2a5772..f293a2a5772 100644 --- a/src/librustc_error_codes/error_codes/E0076.md +++ b/compiler/rustc_error_codes/src/error_codes/E0076.md diff --git a/src/librustc_error_codes/error_codes/E0077.md b/compiler/rustc_error_codes/src/error_codes/E0077.md index b14513c6ccf..b14513c6ccf 100644 --- a/src/librustc_error_codes/error_codes/E0077.md +++ b/compiler/rustc_error_codes/src/error_codes/E0077.md diff --git a/src/librustc_error_codes/error_codes/E0080.md b/compiler/rustc_error_codes/src/error_codes/E0080.md index 7b1bbde6140..7b1bbde6140 100644 --- a/src/librustc_error_codes/error_codes/E0080.md +++ b/compiler/rustc_error_codes/src/error_codes/E0080.md diff --git a/src/librustc_error_codes/error_codes/E0081.md b/compiler/rustc_error_codes/src/error_codes/E0081.md index b834a734cef..b834a734cef 100644 --- a/src/librustc_error_codes/error_codes/E0081.md +++ b/compiler/rustc_error_codes/src/error_codes/E0081.md diff --git a/src/librustc_error_codes/error_codes/E0084.md b/compiler/rustc_error_codes/src/error_codes/E0084.md index 38ce9b43d0a..38ce9b43d0a 100644 --- a/src/librustc_error_codes/error_codes/E0084.md +++ b/compiler/rustc_error_codes/src/error_codes/E0084.md diff --git a/src/librustc_error_codes/error_codes/E0087.md b/compiler/rustc_error_codes/src/error_codes/E0087.md index 9d292186f0f..9d292186f0f 100644 --- a/src/librustc_error_codes/error_codes/E0087.md +++ b/compiler/rustc_error_codes/src/error_codes/E0087.md diff --git a/src/librustc_error_codes/error_codes/E0088.md b/compiler/rustc_error_codes/src/error_codes/E0088.md index 7780ad5b56e..7780ad5b56e 100644 --- a/src/librustc_error_codes/error_codes/E0088.md +++ b/compiler/rustc_error_codes/src/error_codes/E0088.md diff --git a/src/librustc_error_codes/error_codes/E0089.md b/compiler/rustc_error_codes/src/error_codes/E0089.md index 504fbc7b96a..504fbc7b96a 100644 --- a/src/librustc_error_codes/error_codes/E0089.md +++ b/compiler/rustc_error_codes/src/error_codes/E0089.md diff --git a/src/librustc_error_codes/error_codes/E0090.md b/compiler/rustc_error_codes/src/error_codes/E0090.md index e091bb6c9f2..e091bb6c9f2 100644 --- a/src/librustc_error_codes/error_codes/E0090.md +++ b/compiler/rustc_error_codes/src/error_codes/E0090.md diff --git a/src/librustc_error_codes/error_codes/E0091.md b/compiler/rustc_error_codes/src/error_codes/E0091.md index 03cb3280371..03cb3280371 100644 --- a/src/librustc_error_codes/error_codes/E0091.md +++ b/compiler/rustc_error_codes/src/error_codes/E0091.md diff --git a/src/librustc_error_codes/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md index e289534bf7a..e289534bf7a 100644 --- a/src/librustc_error_codes/error_codes/E0092.md +++ b/compiler/rustc_error_codes/src/error_codes/E0092.md diff --git a/src/librustc_error_codes/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md index 8e7de1a9d37..8e7de1a9d37 100644 --- a/src/librustc_error_codes/error_codes/E0093.md +++ b/compiler/rustc_error_codes/src/error_codes/E0093.md diff --git a/src/librustc_error_codes/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md index 42baa65bf9f..42baa65bf9f 100644 --- a/src/librustc_error_codes/error_codes/E0094.md +++ b/compiler/rustc_error_codes/src/error_codes/E0094.md diff --git a/src/librustc_error_codes/error_codes/E0106.md b/compiler/rustc_error_codes/src/error_codes/E0106.md index 60ca1ddc283..60ca1ddc283 100644 --- a/src/librustc_error_codes/error_codes/E0106.md +++ b/compiler/rustc_error_codes/src/error_codes/E0106.md diff --git a/src/librustc_error_codes/error_codes/E0107.md b/compiler/rustc_error_codes/src/error_codes/E0107.md index 4d22b17fe10..4d22b17fe10 100644 --- a/src/librustc_error_codes/error_codes/E0107.md +++ b/compiler/rustc_error_codes/src/error_codes/E0107.md diff --git a/src/librustc_error_codes/error_codes/E0109.md b/compiler/rustc_error_codes/src/error_codes/E0109.md index 2eab9725a6f..2eab9725a6f 100644 --- a/src/librustc_error_codes/error_codes/E0109.md +++ b/compiler/rustc_error_codes/src/error_codes/E0109.md diff --git a/src/librustc_error_codes/error_codes/E0110.md b/compiler/rustc_error_codes/src/error_codes/E0110.md index b9fe406ffb9..b9fe406ffb9 100644 --- a/src/librustc_error_codes/error_codes/E0110.md +++ b/compiler/rustc_error_codes/src/error_codes/E0110.md diff --git a/src/librustc_error_codes/error_codes/E0116.md b/compiler/rustc_error_codes/src/error_codes/E0116.md index ca849c2a128..ca849c2a128 100644 --- a/src/librustc_error_codes/error_codes/E0116.md +++ b/compiler/rustc_error_codes/src/error_codes/E0116.md diff --git a/src/librustc_error_codes/error_codes/E0117.md b/compiler/rustc_error_codes/src/error_codes/E0117.md index 0544667ccca..0544667ccca 100644 --- a/src/librustc_error_codes/error_codes/E0117.md +++ b/compiler/rustc_error_codes/src/error_codes/E0117.md diff --git a/src/librustc_error_codes/error_codes/E0118.md b/compiler/rustc_error_codes/src/error_codes/E0118.md index 5cb5f506e0a..5cb5f506e0a 100644 --- a/src/librustc_error_codes/error_codes/E0118.md +++ b/compiler/rustc_error_codes/src/error_codes/E0118.md diff --git a/src/librustc_error_codes/error_codes/E0119.md b/compiler/rustc_error_codes/src/error_codes/E0119.md index e596349e5e2..e596349e5e2 100644 --- a/src/librustc_error_codes/error_codes/E0119.md +++ b/compiler/rustc_error_codes/src/error_codes/E0119.md diff --git a/src/librustc_error_codes/error_codes/E0120.md b/compiler/rustc_error_codes/src/error_codes/E0120.md index dc7258d8731..dc7258d8731 100644 --- a/src/librustc_error_codes/error_codes/E0120.md +++ b/compiler/rustc_error_codes/src/error_codes/E0120.md diff --git a/src/librustc_error_codes/error_codes/E0121.md b/compiler/rustc_error_codes/src/error_codes/E0121.md index 06fe396d50d..06fe396d50d 100644 --- a/src/librustc_error_codes/error_codes/E0121.md +++ b/compiler/rustc_error_codes/src/error_codes/E0121.md diff --git a/src/librustc_error_codes/error_codes/E0124.md b/compiler/rustc_error_codes/src/error_codes/E0124.md index 8af7cb819cf..8af7cb819cf 100644 --- a/src/librustc_error_codes/error_codes/E0124.md +++ b/compiler/rustc_error_codes/src/error_codes/E0124.md diff --git a/src/librustc_error_codes/error_codes/E0128.md b/compiler/rustc_error_codes/src/error_codes/E0128.md index 6f8dfe3a73b..6f8dfe3a73b 100644 --- a/src/librustc_error_codes/error_codes/E0128.md +++ b/compiler/rustc_error_codes/src/error_codes/E0128.md diff --git a/src/librustc_error_codes/error_codes/E0130.md b/compiler/rustc_error_codes/src/error_codes/E0130.md index a270feaf58c..a270feaf58c 100644 --- a/src/librustc_error_codes/error_codes/E0130.md +++ b/compiler/rustc_error_codes/src/error_codes/E0130.md diff --git a/src/librustc_error_codes/error_codes/E0131.md b/compiler/rustc_error_codes/src/error_codes/E0131.md index ed798d4f881..ed798d4f881 100644 --- a/src/librustc_error_codes/error_codes/E0131.md +++ b/compiler/rustc_error_codes/src/error_codes/E0131.md diff --git a/src/librustc_error_codes/error_codes/E0132.md b/compiler/rustc_error_codes/src/error_codes/E0132.md index a23cc988bdb..a23cc988bdb 100644 --- a/src/librustc_error_codes/error_codes/E0132.md +++ b/compiler/rustc_error_codes/src/error_codes/E0132.md diff --git a/src/librustc_error_codes/error_codes/E0133.md b/compiler/rustc_error_codes/src/error_codes/E0133.md index 1adbcc31356..1adbcc31356 100644 --- a/src/librustc_error_codes/error_codes/E0133.md +++ b/compiler/rustc_error_codes/src/error_codes/E0133.md diff --git a/src/librustc_error_codes/error_codes/E0136.md b/compiler/rustc_error_codes/src/error_codes/E0136.md index b91b52c074c..b91b52c074c 100644 --- a/src/librustc_error_codes/error_codes/E0136.md +++ b/compiler/rustc_error_codes/src/error_codes/E0136.md diff --git a/src/librustc_error_codes/error_codes/E0137.md b/compiler/rustc_error_codes/src/error_codes/E0137.md index 0a02913d236..0a02913d236 100644 --- a/src/librustc_error_codes/error_codes/E0137.md +++ b/compiler/rustc_error_codes/src/error_codes/E0137.md diff --git a/src/librustc_error_codes/error_codes/E0138.md b/compiler/rustc_error_codes/src/error_codes/E0138.md index 3f5eaea9f98..3f5eaea9f98 100644 --- a/src/librustc_error_codes/error_codes/E0138.md +++ b/compiler/rustc_error_codes/src/error_codes/E0138.md diff --git a/src/librustc_error_codes/error_codes/E0139.md b/compiler/rustc_error_codes/src/error_codes/E0139.md index a116cf29395..a116cf29395 100644 --- a/src/librustc_error_codes/error_codes/E0139.md +++ b/compiler/rustc_error_codes/src/error_codes/E0139.md diff --git a/src/librustc_error_codes/error_codes/E0152.md b/compiler/rustc_error_codes/src/error_codes/E0152.md index 120c96b4211..120c96b4211 100644 --- a/src/librustc_error_codes/error_codes/E0152.md +++ b/compiler/rustc_error_codes/src/error_codes/E0152.md diff --git a/src/librustc_error_codes/error_codes/E0154.md b/compiler/rustc_error_codes/src/error_codes/E0154.md index e437a71897c..e437a71897c 100644 --- a/src/librustc_error_codes/error_codes/E0154.md +++ b/compiler/rustc_error_codes/src/error_codes/E0154.md diff --git a/src/librustc_error_codes/error_codes/E0158.md b/compiler/rustc_error_codes/src/error_codes/E0158.md index 0a9ef9c3938..0a9ef9c3938 100644 --- a/src/librustc_error_codes/error_codes/E0158.md +++ b/compiler/rustc_error_codes/src/error_codes/E0158.md diff --git a/src/librustc_error_codes/error_codes/E0161.md b/compiler/rustc_error_codes/src/error_codes/E0161.md index c2e2f0240f4..c2e2f0240f4 100644 --- a/src/librustc_error_codes/error_codes/E0161.md +++ b/compiler/rustc_error_codes/src/error_codes/E0161.md diff --git a/src/librustc_error_codes/error_codes/E0162.md b/compiler/rustc_error_codes/src/error_codes/E0162.md index 98146147f39..98146147f39 100644 --- a/src/librustc_error_codes/error_codes/E0162.md +++ b/compiler/rustc_error_codes/src/error_codes/E0162.md diff --git a/src/librustc_error_codes/error_codes/E0164.md b/compiler/rustc_error_codes/src/error_codes/E0164.md index 48bb6f4b382..48bb6f4b382 100644 --- a/src/librustc_error_codes/error_codes/E0164.md +++ b/compiler/rustc_error_codes/src/error_codes/E0164.md diff --git a/src/librustc_error_codes/error_codes/E0165.md b/compiler/rustc_error_codes/src/error_codes/E0165.md index 92243db4550..92243db4550 100644 --- a/src/librustc_error_codes/error_codes/E0165.md +++ b/compiler/rustc_error_codes/src/error_codes/E0165.md diff --git a/src/librustc_error_codes/error_codes/E0170.md b/compiler/rustc_error_codes/src/error_codes/E0170.md index 9678cd173b7..9678cd173b7 100644 --- a/src/librustc_error_codes/error_codes/E0170.md +++ b/compiler/rustc_error_codes/src/error_codes/E0170.md diff --git a/src/librustc_error_codes/error_codes/E0178.md b/compiler/rustc_error_codes/src/error_codes/E0178.md index 0c6f918632f..0c6f918632f 100644 --- a/src/librustc_error_codes/error_codes/E0178.md +++ b/compiler/rustc_error_codes/src/error_codes/E0178.md diff --git a/src/librustc_error_codes/error_codes/E0184.md b/compiler/rustc_error_codes/src/error_codes/E0184.md index 4624f9e5b85..4624f9e5b85 100644 --- a/src/librustc_error_codes/error_codes/E0184.md +++ b/compiler/rustc_error_codes/src/error_codes/E0184.md diff --git a/src/librustc_error_codes/error_codes/E0185.md b/compiler/rustc_error_codes/src/error_codes/E0185.md index 944a93ed14e..944a93ed14e 100644 --- a/src/librustc_error_codes/error_codes/E0185.md +++ b/compiler/rustc_error_codes/src/error_codes/E0185.md diff --git a/src/librustc_error_codes/error_codes/E0186.md b/compiler/rustc_error_codes/src/error_codes/E0186.md index 7db1e843323..7db1e843323 100644 --- a/src/librustc_error_codes/error_codes/E0186.md +++ b/compiler/rustc_error_codes/src/error_codes/E0186.md diff --git a/src/librustc_error_codes/error_codes/E0191.md b/compiler/rustc_error_codes/src/error_codes/E0191.md index 46b773bdc50..46b773bdc50 100644 --- a/src/librustc_error_codes/error_codes/E0191.md +++ b/compiler/rustc_error_codes/src/error_codes/E0191.md diff --git a/src/librustc_error_codes/error_codes/E0192.md b/compiler/rustc_error_codes/src/error_codes/E0192.md index 5fd951b2e86..5fd951b2e86 100644 --- a/src/librustc_error_codes/error_codes/E0192.md +++ b/compiler/rustc_error_codes/src/error_codes/E0192.md diff --git a/src/librustc_error_codes/error_codes/E0193.md b/compiler/rustc_error_codes/src/error_codes/E0193.md index e29a949ffba..e29a949ffba 100644 --- a/src/librustc_error_codes/error_codes/E0193.md +++ b/compiler/rustc_error_codes/src/error_codes/E0193.md diff --git a/src/librustc_error_codes/error_codes/E0195.md b/compiler/rustc_error_codes/src/error_codes/E0195.md index b8c313d412e..b8c313d412e 100644 --- a/src/librustc_error_codes/error_codes/E0195.md +++ b/compiler/rustc_error_codes/src/error_codes/E0195.md diff --git a/src/librustc_error_codes/error_codes/E0197.md b/compiler/rustc_error_codes/src/error_codes/E0197.md index c142b8f3664..c142b8f3664 100644 --- a/src/librustc_error_codes/error_codes/E0197.md +++ b/compiler/rustc_error_codes/src/error_codes/E0197.md diff --git a/src/librustc_error_codes/error_codes/E0198.md b/compiler/rustc_error_codes/src/error_codes/E0198.md index 90f1e542874..90f1e542874 100644 --- a/src/librustc_error_codes/error_codes/E0198.md +++ b/compiler/rustc_error_codes/src/error_codes/E0198.md diff --git a/src/librustc_error_codes/error_codes/E0199.md b/compiler/rustc_error_codes/src/error_codes/E0199.md index 88130e8e5e5..88130e8e5e5 100644 --- a/src/librustc_error_codes/error_codes/E0199.md +++ b/compiler/rustc_error_codes/src/error_codes/E0199.md diff --git a/src/librustc_error_codes/error_codes/E0200.md b/compiler/rustc_error_codes/src/error_codes/E0200.md index 7245bb59ce5..7245bb59ce5 100644 --- a/src/librustc_error_codes/error_codes/E0200.md +++ b/compiler/rustc_error_codes/src/error_codes/E0200.md diff --git a/src/librustc_error_codes/error_codes/E0201.md b/compiler/rustc_error_codes/src/error_codes/E0201.md index 0e1a7b7b7de..0e1a7b7b7de 100644 --- a/src/librustc_error_codes/error_codes/E0201.md +++ b/compiler/rustc_error_codes/src/error_codes/E0201.md diff --git a/src/librustc_error_codes/error_codes/E0202.md b/compiler/rustc_error_codes/src/error_codes/E0202.md index afc61ec2e48..afc61ec2e48 100644 --- a/src/librustc_error_codes/error_codes/E0202.md +++ b/compiler/rustc_error_codes/src/error_codes/E0202.md diff --git a/src/librustc_error_codes/error_codes/E0203.md b/compiler/rustc_error_codes/src/error_codes/E0203.md index 1edb519275f..1edb519275f 100644 --- a/src/librustc_error_codes/error_codes/E0203.md +++ b/compiler/rustc_error_codes/src/error_codes/E0203.md diff --git a/src/librustc_error_codes/error_codes/E0204.md b/compiler/rustc_error_codes/src/error_codes/E0204.md index 96e44758be4..96e44758be4 100644 --- a/src/librustc_error_codes/error_codes/E0204.md +++ b/compiler/rustc_error_codes/src/error_codes/E0204.md diff --git a/src/librustc_error_codes/error_codes/E0205.md b/compiler/rustc_error_codes/src/error_codes/E0205.md index 7916f53ad3b..7916f53ad3b 100644 --- a/src/librustc_error_codes/error_codes/E0205.md +++ b/compiler/rustc_error_codes/src/error_codes/E0205.md diff --git a/src/librustc_error_codes/error_codes/E0206.md b/compiler/rustc_error_codes/src/error_codes/E0206.md index da53b671ad0..da53b671ad0 100644 --- a/src/librustc_error_codes/error_codes/E0206.md +++ b/compiler/rustc_error_codes/src/error_codes/E0206.md diff --git a/src/librustc_error_codes/error_codes/E0207.md b/compiler/rustc_error_codes/src/error_codes/E0207.md index cb4f5d5157d..cb4f5d5157d 100644 --- a/src/librustc_error_codes/error_codes/E0207.md +++ b/compiler/rustc_error_codes/src/error_codes/E0207.md diff --git a/src/librustc_error_codes/error_codes/E0210.md b/compiler/rustc_error_codes/src/error_codes/E0210.md index dc2fd9b0ca0..dc2fd9b0ca0 100644 --- a/src/librustc_error_codes/error_codes/E0210.md +++ b/compiler/rustc_error_codes/src/error_codes/E0210.md diff --git a/src/librustc_error_codes/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md index 77289f01900..77289f01900 100644 --- a/src/librustc_error_codes/error_codes/E0211.md +++ b/compiler/rustc_error_codes/src/error_codes/E0211.md diff --git a/src/librustc_error_codes/error_codes/E0214.md b/compiler/rustc_error_codes/src/error_codes/E0214.md index b64ee80e284..b64ee80e284 100644 --- a/src/librustc_error_codes/error_codes/E0214.md +++ b/compiler/rustc_error_codes/src/error_codes/E0214.md diff --git a/src/librustc_error_codes/error_codes/E0220.md b/compiler/rustc_error_codes/src/error_codes/E0220.md index ddc54007c8c..ddc54007c8c 100644 --- a/src/librustc_error_codes/error_codes/E0220.md +++ b/compiler/rustc_error_codes/src/error_codes/E0220.md diff --git a/src/librustc_error_codes/error_codes/E0221.md b/compiler/rustc_error_codes/src/error_codes/E0221.md index 26111ca4293..26111ca4293 100644 --- a/src/librustc_error_codes/error_codes/E0221.md +++ b/compiler/rustc_error_codes/src/error_codes/E0221.md diff --git a/src/librustc_error_codes/error_codes/E0222.md b/compiler/rustc_error_codes/src/error_codes/E0222.md index fbf1b8d7033..fbf1b8d7033 100644 --- a/src/librustc_error_codes/error_codes/E0222.md +++ b/compiler/rustc_error_codes/src/error_codes/E0222.md diff --git a/src/librustc_error_codes/error_codes/E0223.md b/compiler/rustc_error_codes/src/error_codes/E0223.md index 0d49f514ccf..0d49f514ccf 100644 --- a/src/librustc_error_codes/error_codes/E0223.md +++ b/compiler/rustc_error_codes/src/error_codes/E0223.md diff --git a/src/librustc_error_codes/error_codes/E0224.md b/compiler/rustc_error_codes/src/error_codes/E0224.md index fd89c1d5256..fd89c1d5256 100644 --- a/src/librustc_error_codes/error_codes/E0224.md +++ b/compiler/rustc_error_codes/src/error_codes/E0224.md diff --git a/src/librustc_error_codes/error_codes/E0225.md b/compiler/rustc_error_codes/src/error_codes/E0225.md index c306e710097..c306e710097 100644 --- a/src/librustc_error_codes/error_codes/E0225.md +++ b/compiler/rustc_error_codes/src/error_codes/E0225.md diff --git a/src/librustc_error_codes/error_codes/E0226.md b/compiler/rustc_error_codes/src/error_codes/E0226.md index 4e65132ff0d..4e65132ff0d 100644 --- a/src/librustc_error_codes/error_codes/E0226.md +++ b/compiler/rustc_error_codes/src/error_codes/E0226.md diff --git a/src/librustc_error_codes/error_codes/E0228.md b/compiler/rustc_error_codes/src/error_codes/E0228.md index 3443a5ae863..3443a5ae863 100644 --- a/src/librustc_error_codes/error_codes/E0228.md +++ b/compiler/rustc_error_codes/src/error_codes/E0228.md diff --git a/src/librustc_error_codes/error_codes/E0229.md b/compiler/rustc_error_codes/src/error_codes/E0229.md index a8fab057d43..a8fab057d43 100644 --- a/src/librustc_error_codes/error_codes/E0229.md +++ b/compiler/rustc_error_codes/src/error_codes/E0229.md diff --git a/src/librustc_error_codes/error_codes/E0230.md b/compiler/rustc_error_codes/src/error_codes/E0230.md index cfb72e74319..cfb72e74319 100644 --- a/src/librustc_error_codes/error_codes/E0230.md +++ b/compiler/rustc_error_codes/src/error_codes/E0230.md diff --git a/src/librustc_error_codes/error_codes/E0231.md b/compiler/rustc_error_codes/src/error_codes/E0231.md index 23a0a88ecdd..23a0a88ecdd 100644 --- a/src/librustc_error_codes/error_codes/E0231.md +++ b/compiler/rustc_error_codes/src/error_codes/E0231.md diff --git a/src/librustc_error_codes/error_codes/E0232.md b/compiler/rustc_error_codes/src/error_codes/E0232.md index b310caefa6e..b310caefa6e 100644 --- a/src/librustc_error_codes/error_codes/E0232.md +++ b/compiler/rustc_error_codes/src/error_codes/E0232.md diff --git a/src/librustc_error_codes/error_codes/E0243.md b/compiler/rustc_error_codes/src/error_codes/E0243.md index 5d3d1828bf5..5d3d1828bf5 100644 --- a/src/librustc_error_codes/error_codes/E0243.md +++ b/compiler/rustc_error_codes/src/error_codes/E0243.md diff --git a/src/librustc_error_codes/error_codes/E0244.md b/compiler/rustc_error_codes/src/error_codes/E0244.md index 5187b7b05d2..5187b7b05d2 100644 --- a/src/librustc_error_codes/error_codes/E0244.md +++ b/compiler/rustc_error_codes/src/error_codes/E0244.md diff --git a/src/librustc_error_codes/error_codes/E0251.md b/compiler/rustc_error_codes/src/error_codes/E0251.md index 4121dd27877..4121dd27877 100644 --- a/src/librustc_error_codes/error_codes/E0251.md +++ b/compiler/rustc_error_codes/src/error_codes/E0251.md diff --git a/src/librustc_error_codes/error_codes/E0252.md b/compiler/rustc_error_codes/src/error_codes/E0252.md index e678944650f..e678944650f 100644 --- a/src/librustc_error_codes/error_codes/E0252.md +++ b/compiler/rustc_error_codes/src/error_codes/E0252.md diff --git a/src/librustc_error_codes/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md index aea51d40238..aea51d40238 100644 --- a/src/librustc_error_codes/error_codes/E0253.md +++ b/compiler/rustc_error_codes/src/error_codes/E0253.md diff --git a/src/librustc_error_codes/error_codes/E0254.md b/compiler/rustc_error_codes/src/error_codes/E0254.md index 44383ed6eab..44383ed6eab 100644 --- a/src/librustc_error_codes/error_codes/E0254.md +++ b/compiler/rustc_error_codes/src/error_codes/E0254.md diff --git a/src/librustc_error_codes/error_codes/E0255.md b/compiler/rustc_error_codes/src/error_codes/E0255.md index 83f5ec3dda4..83f5ec3dda4 100644 --- a/src/librustc_error_codes/error_codes/E0255.md +++ b/compiler/rustc_error_codes/src/error_codes/E0255.md diff --git a/src/librustc_error_codes/error_codes/E0256.md b/compiler/rustc_error_codes/src/error_codes/E0256.md index 385376cdade..385376cdade 100644 --- a/src/librustc_error_codes/error_codes/E0256.md +++ b/compiler/rustc_error_codes/src/error_codes/E0256.md diff --git a/src/librustc_error_codes/error_codes/E0259.md b/compiler/rustc_error_codes/src/error_codes/E0259.md index 8d8f93db30f..8d8f93db30f 100644 --- a/src/librustc_error_codes/error_codes/E0259.md +++ b/compiler/rustc_error_codes/src/error_codes/E0259.md diff --git a/src/librustc_error_codes/error_codes/E0260.md b/compiler/rustc_error_codes/src/error_codes/E0260.md index b8bdb81fcbf..b8bdb81fcbf 100644 --- a/src/librustc_error_codes/error_codes/E0260.md +++ b/compiler/rustc_error_codes/src/error_codes/E0260.md diff --git a/src/librustc_error_codes/error_codes/E0261.md b/compiler/rustc_error_codes/src/error_codes/E0261.md index e3268437396..e3268437396 100644 --- a/src/librustc_error_codes/error_codes/E0261.md +++ b/compiler/rustc_error_codes/src/error_codes/E0261.md diff --git a/src/librustc_error_codes/error_codes/E0262.md b/compiler/rustc_error_codes/src/error_codes/E0262.md index 67419d53ef9..67419d53ef9 100644 --- a/src/librustc_error_codes/error_codes/E0262.md +++ b/compiler/rustc_error_codes/src/error_codes/E0262.md diff --git a/src/librustc_error_codes/error_codes/E0263.md b/compiler/rustc_error_codes/src/error_codes/E0263.md index 37271ac692d..37271ac692d 100644 --- a/src/librustc_error_codes/error_codes/E0263.md +++ b/compiler/rustc_error_codes/src/error_codes/E0263.md diff --git a/src/librustc_error_codes/error_codes/E0264.md b/compiler/rustc_error_codes/src/error_codes/E0264.md index e2a27f7b106..e2a27f7b106 100644 --- a/src/librustc_error_codes/error_codes/E0264.md +++ b/compiler/rustc_error_codes/src/error_codes/E0264.md diff --git a/src/librustc_error_codes/error_codes/E0267.md b/compiler/rustc_error_codes/src/error_codes/E0267.md index 951490df874..951490df874 100644 --- a/src/librustc_error_codes/error_codes/E0267.md +++ b/compiler/rustc_error_codes/src/error_codes/E0267.md diff --git a/src/librustc_error_codes/error_codes/E0268.md b/compiler/rustc_error_codes/src/error_codes/E0268.md index 436aef79fe0..436aef79fe0 100644 --- a/src/librustc_error_codes/error_codes/E0268.md +++ b/compiler/rustc_error_codes/src/error_codes/E0268.md diff --git a/src/librustc_error_codes/error_codes/E0271.md b/compiler/rustc_error_codes/src/error_codes/E0271.md index ddd245b1a2b..ddd245b1a2b 100644 --- a/src/librustc_error_codes/error_codes/E0271.md +++ b/compiler/rustc_error_codes/src/error_codes/E0271.md diff --git a/src/librustc_error_codes/error_codes/E0275.md b/compiler/rustc_error_codes/src/error_codes/E0275.md index 2d12fcea4ca..2d12fcea4ca 100644 --- a/src/librustc_error_codes/error_codes/E0275.md +++ b/compiler/rustc_error_codes/src/error_codes/E0275.md diff --git a/src/librustc_error_codes/error_codes/E0276.md b/compiler/rustc_error_codes/src/error_codes/E0276.md index ad76968c589..ad76968c589 100644 --- a/src/librustc_error_codes/error_codes/E0276.md +++ b/compiler/rustc_error_codes/src/error_codes/E0276.md diff --git a/src/librustc_error_codes/error_codes/E0277.md b/compiler/rustc_error_codes/src/error_codes/E0277.md index 2e2cd5e01fb..2e2cd5e01fb 100644 --- a/src/librustc_error_codes/error_codes/E0277.md +++ b/compiler/rustc_error_codes/src/error_codes/E0277.md diff --git a/src/librustc_error_codes/error_codes/E0281.md b/compiler/rustc_error_codes/src/error_codes/E0281.md index 1d7904b67dd..1d7904b67dd 100644 --- a/src/librustc_error_codes/error_codes/E0281.md +++ b/compiler/rustc_error_codes/src/error_codes/E0281.md diff --git a/src/librustc_error_codes/error_codes/E0282.md b/compiler/rustc_error_codes/src/error_codes/E0282.md index 49d2205f92c..49d2205f92c 100644 --- a/src/librustc_error_codes/error_codes/E0282.md +++ b/compiler/rustc_error_codes/src/error_codes/E0282.md diff --git a/src/librustc_error_codes/error_codes/E0283.md b/compiler/rustc_error_codes/src/error_codes/E0283.md index 6885f9a486d..6885f9a486d 100644 --- a/src/librustc_error_codes/error_codes/E0283.md +++ b/compiler/rustc_error_codes/src/error_codes/E0283.md diff --git a/src/librustc_error_codes/error_codes/E0284.md b/compiler/rustc_error_codes/src/error_codes/E0284.md index a1ffa2bda00..a1ffa2bda00 100644 --- a/src/librustc_error_codes/error_codes/E0284.md +++ b/compiler/rustc_error_codes/src/error_codes/E0284.md diff --git a/src/librustc_error_codes/error_codes/E0297.md b/compiler/rustc_error_codes/src/error_codes/E0297.md index 66c31376d8b..66c31376d8b 100644 --- a/src/librustc_error_codes/error_codes/E0297.md +++ b/compiler/rustc_error_codes/src/error_codes/E0297.md diff --git a/src/librustc_error_codes/error_codes/E0301.md b/compiler/rustc_error_codes/src/error_codes/E0301.md index 485e19fbb8d..485e19fbb8d 100644 --- a/src/librustc_error_codes/error_codes/E0301.md +++ b/compiler/rustc_error_codes/src/error_codes/E0301.md diff --git a/src/librustc_error_codes/error_codes/E0302.md b/compiler/rustc_error_codes/src/error_codes/E0302.md index e6ac9d590c8..e6ac9d590c8 100644 --- a/src/librustc_error_codes/error_codes/E0302.md +++ b/compiler/rustc_error_codes/src/error_codes/E0302.md diff --git a/src/librustc_error_codes/error_codes/E0303.md b/compiler/rustc_error_codes/src/error_codes/E0303.md index 459906047cc..459906047cc 100644 --- a/src/librustc_error_codes/error_codes/E0303.md +++ b/compiler/rustc_error_codes/src/error_codes/E0303.md diff --git a/src/librustc_error_codes/error_codes/E0307.md b/compiler/rustc_error_codes/src/error_codes/E0307.md index 0d29d56ea1a..0d29d56ea1a 100644 --- a/src/librustc_error_codes/error_codes/E0307.md +++ b/compiler/rustc_error_codes/src/error_codes/E0307.md diff --git a/src/librustc_error_codes/error_codes/E0308.md b/compiler/rustc_error_codes/src/error_codes/E0308.md index e2c40f03019..e2c40f03019 100644 --- a/src/librustc_error_codes/error_codes/E0308.md +++ b/compiler/rustc_error_codes/src/error_codes/E0308.md diff --git a/src/librustc_error_codes/error_codes/E0309.md b/compiler/rustc_error_codes/src/error_codes/E0309.md index e719ee590ab..e719ee590ab 100644 --- a/src/librustc_error_codes/error_codes/E0309.md +++ b/compiler/rustc_error_codes/src/error_codes/E0309.md diff --git a/src/librustc_error_codes/error_codes/E0310.md b/compiler/rustc_error_codes/src/error_codes/E0310.md index 8d4311d018b..8d4311d018b 100644 --- a/src/librustc_error_codes/error_codes/E0310.md +++ b/compiler/rustc_error_codes/src/error_codes/E0310.md diff --git a/src/librustc_error_codes/error_codes/E0312.md b/compiler/rustc_error_codes/src/error_codes/E0312.md index cb090d01382..cb090d01382 100644 --- a/src/librustc_error_codes/error_codes/E0312.md +++ b/compiler/rustc_error_codes/src/error_codes/E0312.md diff --git a/src/librustc_error_codes/error_codes/E0317.md b/compiler/rustc_error_codes/src/error_codes/E0317.md index 230911c2086..230911c2086 100644 --- a/src/librustc_error_codes/error_codes/E0317.md +++ b/compiler/rustc_error_codes/src/error_codes/E0317.md diff --git a/src/librustc_error_codes/error_codes/E0321.md b/compiler/rustc_error_codes/src/error_codes/E0321.md index bfcdabfe9de..bfcdabfe9de 100644 --- a/src/librustc_error_codes/error_codes/E0321.md +++ b/compiler/rustc_error_codes/src/error_codes/E0321.md diff --git a/src/librustc_error_codes/error_codes/E0322.md b/compiler/rustc_error_codes/src/error_codes/E0322.md index ccef8681dd6..ccef8681dd6 100644 --- a/src/librustc_error_codes/error_codes/E0322.md +++ b/compiler/rustc_error_codes/src/error_codes/E0322.md diff --git a/src/librustc_error_codes/error_codes/E0323.md b/compiler/rustc_error_codes/src/error_codes/E0323.md index 0bf42d17ebc..0bf42d17ebc 100644 --- a/src/librustc_error_codes/error_codes/E0323.md +++ b/compiler/rustc_error_codes/src/error_codes/E0323.md diff --git a/src/librustc_error_codes/error_codes/E0324.md b/compiler/rustc_error_codes/src/error_codes/E0324.md index 1442cb77dd9..1442cb77dd9 100644 --- a/src/librustc_error_codes/error_codes/E0324.md +++ b/compiler/rustc_error_codes/src/error_codes/E0324.md diff --git a/src/librustc_error_codes/error_codes/E0325.md b/compiler/rustc_error_codes/src/error_codes/E0325.md index 656fd1ec82b..656fd1ec82b 100644 --- a/src/librustc_error_codes/error_codes/E0325.md +++ b/compiler/rustc_error_codes/src/error_codes/E0325.md diff --git a/src/librustc_error_codes/error_codes/E0326.md b/compiler/rustc_error_codes/src/error_codes/E0326.md index bc522e9cf40..bc522e9cf40 100644 --- a/src/librustc_error_codes/error_codes/E0326.md +++ b/compiler/rustc_error_codes/src/error_codes/E0326.md diff --git a/src/librustc_error_codes/error_codes/E0328.md b/compiler/rustc_error_codes/src/error_codes/E0328.md index 83909235455..83909235455 100644 --- a/src/librustc_error_codes/error_codes/E0328.md +++ b/compiler/rustc_error_codes/src/error_codes/E0328.md diff --git a/src/librustc_error_codes/error_codes/E0329.md b/compiler/rustc_error_codes/src/error_codes/E0329.md index 37d84a1a89b..37d84a1a89b 100644 --- a/src/librustc_error_codes/error_codes/E0329.md +++ b/compiler/rustc_error_codes/src/error_codes/E0329.md diff --git a/src/librustc_error_codes/error_codes/E0364.md b/compiler/rustc_error_codes/src/error_codes/E0364.md index d01fb0c9c42..d01fb0c9c42 100644 --- a/src/librustc_error_codes/error_codes/E0364.md +++ b/compiler/rustc_error_codes/src/error_codes/E0364.md diff --git a/src/librustc_error_codes/error_codes/E0365.md b/compiler/rustc_error_codes/src/error_codes/E0365.md index e3d417a7d01..e3d417a7d01 100644 --- a/src/librustc_error_codes/error_codes/E0365.md +++ b/compiler/rustc_error_codes/src/error_codes/E0365.md diff --git a/src/librustc_error_codes/error_codes/E0366.md b/compiler/rustc_error_codes/src/error_codes/E0366.md index e6f8e61893b..e6f8e61893b 100644 --- a/src/librustc_error_codes/error_codes/E0366.md +++ b/compiler/rustc_error_codes/src/error_codes/E0366.md diff --git a/src/librustc_error_codes/error_codes/E0367.md b/compiler/rustc_error_codes/src/error_codes/E0367.md index cfebeada272..cfebeada272 100644 --- a/src/librustc_error_codes/error_codes/E0367.md +++ b/compiler/rustc_error_codes/src/error_codes/E0367.md diff --git a/src/librustc_error_codes/error_codes/E0368.md b/compiler/rustc_error_codes/src/error_codes/E0368.md index 7b9d9334821..7b9d9334821 100644 --- a/src/librustc_error_codes/error_codes/E0368.md +++ b/compiler/rustc_error_codes/src/error_codes/E0368.md diff --git a/src/librustc_error_codes/error_codes/E0369.md b/compiler/rustc_error_codes/src/error_codes/E0369.md index ab0f4b40843..ab0f4b40843 100644 --- a/src/librustc_error_codes/error_codes/E0369.md +++ b/compiler/rustc_error_codes/src/error_codes/E0369.md diff --git a/src/librustc_error_codes/error_codes/E0370.md b/compiler/rustc_error_codes/src/error_codes/E0370.md index 14e954722a2..14e954722a2 100644 --- a/src/librustc_error_codes/error_codes/E0370.md +++ b/compiler/rustc_error_codes/src/error_codes/E0370.md diff --git a/src/librustc_error_codes/error_codes/E0371.md b/compiler/rustc_error_codes/src/error_codes/E0371.md index a44721346e2..a44721346e2 100644 --- a/src/librustc_error_codes/error_codes/E0371.md +++ b/compiler/rustc_error_codes/src/error_codes/E0371.md diff --git a/src/librustc_error_codes/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md index fd969877931..fd969877931 100644 --- a/src/librustc_error_codes/error_codes/E0373.md +++ b/compiler/rustc_error_codes/src/error_codes/E0373.md diff --git a/src/librustc_error_codes/error_codes/E0374.md b/compiler/rustc_error_codes/src/error_codes/E0374.md index 6d7dc88823c..6d7dc88823c 100644 --- a/src/librustc_error_codes/error_codes/E0374.md +++ b/compiler/rustc_error_codes/src/error_codes/E0374.md diff --git a/src/librustc_error_codes/error_codes/E0375.md b/compiler/rustc_error_codes/src/error_codes/E0375.md index 71e53057165..71e53057165 100644 --- a/src/librustc_error_codes/error_codes/E0375.md +++ b/compiler/rustc_error_codes/src/error_codes/E0375.md diff --git a/src/librustc_error_codes/error_codes/E0376.md b/compiler/rustc_error_codes/src/error_codes/E0376.md index 50de15bd30f..50de15bd30f 100644 --- a/src/librustc_error_codes/error_codes/E0376.md +++ b/compiler/rustc_error_codes/src/error_codes/E0376.md diff --git a/src/librustc_error_codes/error_codes/E0378.md b/compiler/rustc_error_codes/src/error_codes/E0378.md index c6fe997f3dc..c6fe997f3dc 100644 --- a/src/librustc_error_codes/error_codes/E0378.md +++ b/compiler/rustc_error_codes/src/error_codes/E0378.md diff --git a/src/librustc_error_codes/error_codes/E0379.md b/compiler/rustc_error_codes/src/error_codes/E0379.md index 930204847ec..930204847ec 100644 --- a/src/librustc_error_codes/error_codes/E0379.md +++ b/compiler/rustc_error_codes/src/error_codes/E0379.md diff --git a/src/librustc_error_codes/error_codes/E0380.md b/compiler/rustc_error_codes/src/error_codes/E0380.md index 638f0c8ecc6..638f0c8ecc6 100644 --- a/src/librustc_error_codes/error_codes/E0380.md +++ b/compiler/rustc_error_codes/src/error_codes/E0380.md diff --git a/src/librustc_error_codes/error_codes/E0381.md b/compiler/rustc_error_codes/src/error_codes/E0381.md index 97678009925..97678009925 100644 --- a/src/librustc_error_codes/error_codes/E0381.md +++ b/compiler/rustc_error_codes/src/error_codes/E0381.md diff --git a/src/librustc_error_codes/error_codes/E0382.md b/compiler/rustc_error_codes/src/error_codes/E0382.md index d1408a06296..d1408a06296 100644 --- a/src/librustc_error_codes/error_codes/E0382.md +++ b/compiler/rustc_error_codes/src/error_codes/E0382.md diff --git a/src/librustc_error_codes/error_codes/E0383.md b/compiler/rustc_error_codes/src/error_codes/E0383.md index fd2b0b08fb0..fd2b0b08fb0 100644 --- a/src/librustc_error_codes/error_codes/E0383.md +++ b/compiler/rustc_error_codes/src/error_codes/E0383.md diff --git a/src/librustc_error_codes/error_codes/E0384.md b/compiler/rustc_error_codes/src/error_codes/E0384.md index e21fac0797c..e21fac0797c 100644 --- a/src/librustc_error_codes/error_codes/E0384.md +++ b/compiler/rustc_error_codes/src/error_codes/E0384.md diff --git a/src/librustc_error_codes/error_codes/E0386.md b/compiler/rustc_error_codes/src/error_codes/E0386.md index de3b468b6e4..de3b468b6e4 100644 --- a/src/librustc_error_codes/error_codes/E0386.md +++ b/compiler/rustc_error_codes/src/error_codes/E0386.md diff --git a/src/librustc_error_codes/error_codes/E0387.md b/compiler/rustc_error_codes/src/error_codes/E0387.md index 38ad19bd6aa..38ad19bd6aa 100644 --- a/src/librustc_error_codes/error_codes/E0387.md +++ b/compiler/rustc_error_codes/src/error_codes/E0387.md diff --git a/src/librustc_error_codes/error_codes/E0388.md b/compiler/rustc_error_codes/src/error_codes/E0388.md index 512fb42e6ec..512fb42e6ec 100644 --- a/src/librustc_error_codes/error_codes/E0388.md +++ b/compiler/rustc_error_codes/src/error_codes/E0388.md diff --git a/src/librustc_error_codes/error_codes/E0389.md b/compiler/rustc_error_codes/src/error_codes/E0389.md index 9f064e44c82..9f064e44c82 100644 --- a/src/librustc_error_codes/error_codes/E0389.md +++ b/compiler/rustc_error_codes/src/error_codes/E0389.md diff --git a/src/librustc_error_codes/error_codes/E0390.md b/compiler/rustc_error_codes/src/error_codes/E0390.md index ecc5b5568ad..ecc5b5568ad 100644 --- a/src/librustc_error_codes/error_codes/E0390.md +++ b/compiler/rustc_error_codes/src/error_codes/E0390.md diff --git a/src/librustc_error_codes/error_codes/E0391.md b/compiler/rustc_error_codes/src/error_codes/E0391.md index dff50ccaa0b..dff50ccaa0b 100644 --- a/src/librustc_error_codes/error_codes/E0391.md +++ b/compiler/rustc_error_codes/src/error_codes/E0391.md diff --git a/src/librustc_error_codes/error_codes/E0392.md b/compiler/rustc_error_codes/src/error_codes/E0392.md index f373d89456d..f373d89456d 100644 --- a/src/librustc_error_codes/error_codes/E0392.md +++ b/compiler/rustc_error_codes/src/error_codes/E0392.md diff --git a/src/librustc_error_codes/error_codes/E0393.md b/compiler/rustc_error_codes/src/error_codes/E0393.md index 3e853cf1b8a..3e853cf1b8a 100644 --- a/src/librustc_error_codes/error_codes/E0393.md +++ b/compiler/rustc_error_codes/src/error_codes/E0393.md diff --git a/src/librustc_error_codes/error_codes/E0398.md b/compiler/rustc_error_codes/src/error_codes/E0398.md index 75d86979e3c..75d86979e3c 100644 --- a/src/librustc_error_codes/error_codes/E0398.md +++ b/compiler/rustc_error_codes/src/error_codes/E0398.md diff --git a/src/librustc_error_codes/error_codes/E0399.md b/compiler/rustc_error_codes/src/error_codes/E0399.md index 6ea6054b417..6ea6054b417 100644 --- a/src/librustc_error_codes/error_codes/E0399.md +++ b/compiler/rustc_error_codes/src/error_codes/E0399.md diff --git a/src/librustc_error_codes/error_codes/E0401.md b/compiler/rustc_error_codes/src/error_codes/E0401.md index 4c93053d5f8..4c93053d5f8 100644 --- a/src/librustc_error_codes/error_codes/E0401.md +++ b/compiler/rustc_error_codes/src/error_codes/E0401.md diff --git a/src/librustc_error_codes/error_codes/E0403.md b/compiler/rustc_error_codes/src/error_codes/E0403.md index 5f4a40ce92e..5f4a40ce92e 100644 --- a/src/librustc_error_codes/error_codes/E0403.md +++ b/compiler/rustc_error_codes/src/error_codes/E0403.md diff --git a/src/librustc_error_codes/error_codes/E0404.md b/compiler/rustc_error_codes/src/error_codes/E0404.md index 1360cc99afc..1360cc99afc 100644 --- a/src/librustc_error_codes/error_codes/E0404.md +++ b/compiler/rustc_error_codes/src/error_codes/E0404.md diff --git a/src/librustc_error_codes/error_codes/E0405.md b/compiler/rustc_error_codes/src/error_codes/E0405.md index ff1e8c0be88..ff1e8c0be88 100644 --- a/src/librustc_error_codes/error_codes/E0405.md +++ b/compiler/rustc_error_codes/src/error_codes/E0405.md diff --git a/src/librustc_error_codes/error_codes/E0407.md b/compiler/rustc_error_codes/src/error_codes/E0407.md index fa26c77a1b0..fa26c77a1b0 100644 --- a/src/librustc_error_codes/error_codes/E0407.md +++ b/compiler/rustc_error_codes/src/error_codes/E0407.md diff --git a/src/librustc_error_codes/error_codes/E0408.md b/compiler/rustc_error_codes/src/error_codes/E0408.md index 3acdbb740a3..3acdbb740a3 100644 --- a/src/librustc_error_codes/error_codes/E0408.md +++ b/compiler/rustc_error_codes/src/error_codes/E0408.md diff --git a/src/librustc_error_codes/error_codes/E0409.md b/compiler/rustc_error_codes/src/error_codes/E0409.md index 53eb0fd0573..53eb0fd0573 100644 --- a/src/librustc_error_codes/error_codes/E0409.md +++ b/compiler/rustc_error_codes/src/error_codes/E0409.md diff --git a/src/librustc_error_codes/error_codes/E0411.md b/compiler/rustc_error_codes/src/error_codes/E0411.md index d82171533ae..d82171533ae 100644 --- a/src/librustc_error_codes/error_codes/E0411.md +++ b/compiler/rustc_error_codes/src/error_codes/E0411.md diff --git a/src/librustc_error_codes/error_codes/E0412.md b/compiler/rustc_error_codes/src/error_codes/E0412.md index d9ebc852bba..d9ebc852bba 100644 --- a/src/librustc_error_codes/error_codes/E0412.md +++ b/compiler/rustc_error_codes/src/error_codes/E0412.md diff --git a/src/librustc_error_codes/error_codes/E0415.md b/compiler/rustc_error_codes/src/error_codes/E0415.md index 97d733a7b2d..97d733a7b2d 100644 --- a/src/librustc_error_codes/error_codes/E0415.md +++ b/compiler/rustc_error_codes/src/error_codes/E0415.md diff --git a/src/librustc_error_codes/error_codes/E0416.md b/compiler/rustc_error_codes/src/error_codes/E0416.md index 7bc316dafc5..7bc316dafc5 100644 --- a/src/librustc_error_codes/error_codes/E0416.md +++ b/compiler/rustc_error_codes/src/error_codes/E0416.md diff --git a/src/librustc_error_codes/error_codes/E0422.md b/compiler/rustc_error_codes/src/error_codes/E0422.md index 828a52e7341..828a52e7341 100644 --- a/src/librustc_error_codes/error_codes/E0422.md +++ b/compiler/rustc_error_codes/src/error_codes/E0422.md diff --git a/src/librustc_error_codes/error_codes/E0423.md b/compiler/rustc_error_codes/src/error_codes/E0423.md index a98ada17a46..a98ada17a46 100644 --- a/src/librustc_error_codes/error_codes/E0423.md +++ b/compiler/rustc_error_codes/src/error_codes/E0423.md diff --git a/src/librustc_error_codes/error_codes/E0424.md b/compiler/rustc_error_codes/src/error_codes/E0424.md index a9f6f579b42..a9f6f579b42 100644 --- a/src/librustc_error_codes/error_codes/E0424.md +++ b/compiler/rustc_error_codes/src/error_codes/E0424.md diff --git a/src/librustc_error_codes/error_codes/E0425.md b/compiler/rustc_error_codes/src/error_codes/E0425.md index 13e71b85065..13e71b85065 100644 --- a/src/librustc_error_codes/error_codes/E0425.md +++ b/compiler/rustc_error_codes/src/error_codes/E0425.md diff --git a/src/librustc_error_codes/error_codes/E0426.md b/compiler/rustc_error_codes/src/error_codes/E0426.md index 275a83e606e..275a83e606e 100644 --- a/src/librustc_error_codes/error_codes/E0426.md +++ b/compiler/rustc_error_codes/src/error_codes/E0426.md diff --git a/src/librustc_error_codes/error_codes/E0428.md b/compiler/rustc_error_codes/src/error_codes/E0428.md index 38db0b4bcf9..38db0b4bcf9 100644 --- a/src/librustc_error_codes/error_codes/E0428.md +++ b/compiler/rustc_error_codes/src/error_codes/E0428.md diff --git a/src/librustc_error_codes/error_codes/E0429.md b/compiler/rustc_error_codes/src/error_codes/E0429.md index 8c5fd8624fd..8c5fd8624fd 100644 --- a/src/librustc_error_codes/error_codes/E0429.md +++ b/compiler/rustc_error_codes/src/error_codes/E0429.md diff --git a/src/librustc_error_codes/error_codes/E0430.md b/compiler/rustc_error_codes/src/error_codes/E0430.md index 8cca0f21e59..8cca0f21e59 100644 --- a/src/librustc_error_codes/error_codes/E0430.md +++ b/compiler/rustc_error_codes/src/error_codes/E0430.md diff --git a/src/librustc_error_codes/error_codes/E0431.md b/compiler/rustc_error_codes/src/error_codes/E0431.md index 1b70f5f1d7b..1b70f5f1d7b 100644 --- a/src/librustc_error_codes/error_codes/E0431.md +++ b/compiler/rustc_error_codes/src/error_codes/E0431.md diff --git a/src/librustc_error_codes/error_codes/E0432.md b/compiler/rustc_error_codes/src/error_codes/E0432.md index a6e2acac5d2..a6e2acac5d2 100644 --- a/src/librustc_error_codes/error_codes/E0432.md +++ b/compiler/rustc_error_codes/src/error_codes/E0432.md diff --git a/src/librustc_error_codes/error_codes/E0433.md b/compiler/rustc_error_codes/src/error_codes/E0433.md index f9e333e8ccd..f9e333e8ccd 100644 --- a/src/librustc_error_codes/error_codes/E0433.md +++ b/compiler/rustc_error_codes/src/error_codes/E0433.md diff --git a/src/librustc_error_codes/error_codes/E0434.md b/compiler/rustc_error_codes/src/error_codes/E0434.md index 8fd60412baf..8fd60412baf 100644 --- a/src/librustc_error_codes/error_codes/E0434.md +++ b/compiler/rustc_error_codes/src/error_codes/E0434.md diff --git a/src/librustc_error_codes/error_codes/E0435.md b/compiler/rustc_error_codes/src/error_codes/E0435.md index 424e5ce1e2e..424e5ce1e2e 100644 --- a/src/librustc_error_codes/error_codes/E0435.md +++ b/compiler/rustc_error_codes/src/error_codes/E0435.md diff --git a/src/librustc_error_codes/error_codes/E0436.md b/compiler/rustc_error_codes/src/error_codes/E0436.md index 48ecc49e92f..48ecc49e92f 100644 --- a/src/librustc_error_codes/error_codes/E0436.md +++ b/compiler/rustc_error_codes/src/error_codes/E0436.md diff --git a/src/librustc_error_codes/error_codes/E0437.md b/compiler/rustc_error_codes/src/error_codes/E0437.md index 0f924ba6920..0f924ba6920 100644 --- a/src/librustc_error_codes/error_codes/E0437.md +++ b/compiler/rustc_error_codes/src/error_codes/E0437.md diff --git a/src/librustc_error_codes/error_codes/E0438.md b/compiler/rustc_error_codes/src/error_codes/E0438.md index 13723bc3009..13723bc3009 100644 --- a/src/librustc_error_codes/error_codes/E0438.md +++ b/compiler/rustc_error_codes/src/error_codes/E0438.md diff --git a/src/librustc_error_codes/error_codes/E0439.md b/compiler/rustc_error_codes/src/error_codes/E0439.md index 3e663df866c..3e663df866c 100644 --- a/src/librustc_error_codes/error_codes/E0439.md +++ b/compiler/rustc_error_codes/src/error_codes/E0439.md diff --git a/src/librustc_error_codes/error_codes/E0445.md b/compiler/rustc_error_codes/src/error_codes/E0445.md index e6a28a9c2c4..e6a28a9c2c4 100644 --- a/src/librustc_error_codes/error_codes/E0445.md +++ b/compiler/rustc_error_codes/src/error_codes/E0445.md diff --git a/src/librustc_error_codes/error_codes/E0446.md b/compiler/rustc_error_codes/src/error_codes/E0446.md index 6ec47c4962c..6ec47c4962c 100644 --- a/src/librustc_error_codes/error_codes/E0446.md +++ b/compiler/rustc_error_codes/src/error_codes/E0446.md diff --git a/src/librustc_error_codes/error_codes/E0447.md b/compiler/rustc_error_codes/src/error_codes/E0447.md index af8cd8d6d52..af8cd8d6d52 100644 --- a/src/librustc_error_codes/error_codes/E0447.md +++ b/compiler/rustc_error_codes/src/error_codes/E0447.md diff --git a/src/librustc_error_codes/error_codes/E0448.md b/compiler/rustc_error_codes/src/error_codes/E0448.md index ba096f9e984..ba096f9e984 100644 --- a/src/librustc_error_codes/error_codes/E0448.md +++ b/compiler/rustc_error_codes/src/error_codes/E0448.md diff --git a/src/librustc_error_codes/error_codes/E0449.md b/compiler/rustc_error_codes/src/error_codes/E0449.md index 9afc67689bf..9afc67689bf 100644 --- a/src/librustc_error_codes/error_codes/E0449.md +++ b/compiler/rustc_error_codes/src/error_codes/E0449.md diff --git a/src/librustc_error_codes/error_codes/E0451.md b/compiler/rustc_error_codes/src/error_codes/E0451.md index 821073fe16e..821073fe16e 100644 --- a/src/librustc_error_codes/error_codes/E0451.md +++ b/compiler/rustc_error_codes/src/error_codes/E0451.md diff --git a/src/librustc_error_codes/error_codes/E0452.md b/compiler/rustc_error_codes/src/error_codes/E0452.md index 429813a7cdd..429813a7cdd 100644 --- a/src/librustc_error_codes/error_codes/E0452.md +++ b/compiler/rustc_error_codes/src/error_codes/E0452.md diff --git a/src/librustc_error_codes/error_codes/E0453.md b/compiler/rustc_error_codes/src/error_codes/E0453.md index 11789db8f36..11789db8f36 100644 --- a/src/librustc_error_codes/error_codes/E0453.md +++ b/compiler/rustc_error_codes/src/error_codes/E0453.md diff --git a/src/librustc_error_codes/error_codes/E0454.md b/compiler/rustc_error_codes/src/error_codes/E0454.md index 23ca6c7824d..23ca6c7824d 100644 --- a/src/librustc_error_codes/error_codes/E0454.md +++ b/compiler/rustc_error_codes/src/error_codes/E0454.md diff --git a/src/librustc_error_codes/error_codes/E0455.md b/compiler/rustc_error_codes/src/error_codes/E0455.md index 2f80c34b889..2f80c34b889 100644 --- a/src/librustc_error_codes/error_codes/E0455.md +++ b/compiler/rustc_error_codes/src/error_codes/E0455.md diff --git a/src/librustc_error_codes/error_codes/E0458.md b/compiler/rustc_error_codes/src/error_codes/E0458.md index 075226ac98b..075226ac98b 100644 --- a/src/librustc_error_codes/error_codes/E0458.md +++ b/compiler/rustc_error_codes/src/error_codes/E0458.md diff --git a/src/librustc_error_codes/error_codes/E0459.md b/compiler/rustc_error_codes/src/error_codes/E0459.md index 6f75f2a99a5..6f75f2a99a5 100644 --- a/src/librustc_error_codes/error_codes/E0459.md +++ b/compiler/rustc_error_codes/src/error_codes/E0459.md diff --git a/src/librustc_error_codes/error_codes/E0463.md b/compiler/rustc_error_codes/src/error_codes/E0463.md index e46938c607d..e46938c607d 100644 --- a/src/librustc_error_codes/error_codes/E0463.md +++ b/compiler/rustc_error_codes/src/error_codes/E0463.md diff --git a/src/librustc_error_codes/error_codes/E0466.md b/compiler/rustc_error_codes/src/error_codes/E0466.md index 7aefedbc087..7aefedbc087 100644 --- a/src/librustc_error_codes/error_codes/E0466.md +++ b/compiler/rustc_error_codes/src/error_codes/E0466.md diff --git a/src/librustc_error_codes/error_codes/E0468.md b/compiler/rustc_error_codes/src/error_codes/E0468.md index cf8664718fa..cf8664718fa 100644 --- a/src/librustc_error_codes/error_codes/E0468.md +++ b/compiler/rustc_error_codes/src/error_codes/E0468.md diff --git a/src/librustc_error_codes/error_codes/E0469.md b/compiler/rustc_error_codes/src/error_codes/E0469.md index 22db976aac2..22db976aac2 100644 --- a/src/librustc_error_codes/error_codes/E0469.md +++ b/compiler/rustc_error_codes/src/error_codes/E0469.md diff --git a/src/librustc_error_codes/error_codes/E0477.md b/compiler/rustc_error_codes/src/error_codes/E0477.md index 9cfefb1de63..9cfefb1de63 100644 --- a/src/librustc_error_codes/error_codes/E0477.md +++ b/compiler/rustc_error_codes/src/error_codes/E0477.md diff --git a/src/librustc_error_codes/error_codes/E0478.md b/compiler/rustc_error_codes/src/error_codes/E0478.md index 4bc5fde2e89..4bc5fde2e89 100644 --- a/src/librustc_error_codes/error_codes/E0478.md +++ b/compiler/rustc_error_codes/src/error_codes/E0478.md diff --git a/src/librustc_error_codes/error_codes/E0491.md b/compiler/rustc_error_codes/src/error_codes/E0491.md index d45663f3a53..d45663f3a53 100644 --- a/src/librustc_error_codes/error_codes/E0491.md +++ b/compiler/rustc_error_codes/src/error_codes/E0491.md diff --git a/src/librustc_error_codes/error_codes/E0492.md b/compiler/rustc_error_codes/src/error_codes/E0492.md index 1caa59999ae..1caa59999ae 100644 --- a/src/librustc_error_codes/error_codes/E0492.md +++ b/compiler/rustc_error_codes/src/error_codes/E0492.md diff --git a/src/librustc_error_codes/error_codes/E0493.md b/compiler/rustc_error_codes/src/error_codes/E0493.md index 0dcc3b62b4b..0dcc3b62b4b 100644 --- a/src/librustc_error_codes/error_codes/E0493.md +++ b/compiler/rustc_error_codes/src/error_codes/E0493.md diff --git a/src/librustc_error_codes/error_codes/E0495.md b/compiler/rustc_error_codes/src/error_codes/E0495.md index f956237b80b..f956237b80b 100644 --- a/src/librustc_error_codes/error_codes/E0495.md +++ b/compiler/rustc_error_codes/src/error_codes/E0495.md diff --git a/src/librustc_error_codes/error_codes/E0496.md b/compiler/rustc_error_codes/src/error_codes/E0496.md index 83d65cd3e09..83d65cd3e09 100644 --- a/src/librustc_error_codes/error_codes/E0496.md +++ b/compiler/rustc_error_codes/src/error_codes/E0496.md diff --git a/src/librustc_error_codes/error_codes/E0497.md b/compiler/rustc_error_codes/src/error_codes/E0497.md index ef2882415d2..ef2882415d2 100644 --- a/src/librustc_error_codes/error_codes/E0497.md +++ b/compiler/rustc_error_codes/src/error_codes/E0497.md diff --git a/src/librustc_error_codes/error_codes/E0499.md b/compiler/rustc_error_codes/src/error_codes/E0499.md index a07e8eb3b38..a07e8eb3b38 100644 --- a/src/librustc_error_codes/error_codes/E0499.md +++ b/compiler/rustc_error_codes/src/error_codes/E0499.md diff --git a/src/librustc_error_codes/error_codes/E0500.md b/compiler/rustc_error_codes/src/error_codes/E0500.md index fde31d2c745..fde31d2c745 100644 --- a/src/librustc_error_codes/error_codes/E0500.md +++ b/compiler/rustc_error_codes/src/error_codes/E0500.md diff --git a/src/librustc_error_codes/error_codes/E0501.md b/compiler/rustc_error_codes/src/error_codes/E0501.md index ffdbc443905..ffdbc443905 100644 --- a/src/librustc_error_codes/error_codes/E0501.md +++ b/compiler/rustc_error_codes/src/error_codes/E0501.md diff --git a/src/librustc_error_codes/error_codes/E0502.md b/compiler/rustc_error_codes/src/error_codes/E0502.md index dc3ffdfddd9..dc3ffdfddd9 100644 --- a/src/librustc_error_codes/error_codes/E0502.md +++ b/compiler/rustc_error_codes/src/error_codes/E0502.md diff --git a/src/librustc_error_codes/error_codes/E0503.md b/compiler/rustc_error_codes/src/error_codes/E0503.md index c52525fee54..c52525fee54 100644 --- a/src/librustc_error_codes/error_codes/E0503.md +++ b/compiler/rustc_error_codes/src/error_codes/E0503.md diff --git a/src/librustc_error_codes/error_codes/E0504.md b/compiler/rustc_error_codes/src/error_codes/E0504.md index bcbd00a8690..bcbd00a8690 100644 --- a/src/librustc_error_codes/error_codes/E0504.md +++ b/compiler/rustc_error_codes/src/error_codes/E0504.md diff --git a/src/librustc_error_codes/error_codes/E0505.md b/compiler/rustc_error_codes/src/error_codes/E0505.md index b11e3c0e947..b11e3c0e947 100644 --- a/src/librustc_error_codes/error_codes/E0505.md +++ b/compiler/rustc_error_codes/src/error_codes/E0505.md diff --git a/src/librustc_error_codes/error_codes/E0506.md b/compiler/rustc_error_codes/src/error_codes/E0506.md index c312a0460e3..c312a0460e3 100644 --- a/src/librustc_error_codes/error_codes/E0506.md +++ b/compiler/rustc_error_codes/src/error_codes/E0506.md diff --git a/src/librustc_error_codes/error_codes/E0507.md b/compiler/rustc_error_codes/src/error_codes/E0507.md index 254751fc45e..254751fc45e 100644 --- a/src/librustc_error_codes/error_codes/E0507.md +++ b/compiler/rustc_error_codes/src/error_codes/E0507.md diff --git a/src/librustc_error_codes/error_codes/E0508.md b/compiler/rustc_error_codes/src/error_codes/E0508.md index 33572fca6a3..33572fca6a3 100644 --- a/src/librustc_error_codes/error_codes/E0508.md +++ b/compiler/rustc_error_codes/src/error_codes/E0508.md diff --git a/src/librustc_error_codes/error_codes/E0509.md b/compiler/rustc_error_codes/src/error_codes/E0509.md index 9cbd7d695aa..9cbd7d695aa 100644 --- a/src/librustc_error_codes/error_codes/E0509.md +++ b/compiler/rustc_error_codes/src/error_codes/E0509.md diff --git a/src/librustc_error_codes/error_codes/E0510.md b/compiler/rustc_error_codes/src/error_codes/E0510.md index e045e04bdbe..e045e04bdbe 100644 --- a/src/librustc_error_codes/error_codes/E0510.md +++ b/compiler/rustc_error_codes/src/error_codes/E0510.md diff --git a/src/librustc_error_codes/error_codes/E0511.md b/compiler/rustc_error_codes/src/error_codes/E0511.md index 5351a685eb5..5351a685eb5 100644 --- a/src/librustc_error_codes/error_codes/E0511.md +++ b/compiler/rustc_error_codes/src/error_codes/E0511.md diff --git a/src/librustc_error_codes/error_codes/E0512.md b/compiler/rustc_error_codes/src/error_codes/E0512.md index 00c09612285..00c09612285 100644 --- a/src/librustc_error_codes/error_codes/E0512.md +++ b/compiler/rustc_error_codes/src/error_codes/E0512.md diff --git a/src/librustc_error_codes/error_codes/E0515.md b/compiler/rustc_error_codes/src/error_codes/E0515.md index 0f4fbf67223..0f4fbf67223 100644 --- a/src/librustc_error_codes/error_codes/E0515.md +++ b/compiler/rustc_error_codes/src/error_codes/E0515.md diff --git a/src/librustc_error_codes/error_codes/E0516.md b/compiler/rustc_error_codes/src/error_codes/E0516.md index 935c31bbab9..935c31bbab9 100644 --- a/src/librustc_error_codes/error_codes/E0516.md +++ b/compiler/rustc_error_codes/src/error_codes/E0516.md diff --git a/src/librustc_error_codes/error_codes/E0517.md b/compiler/rustc_error_codes/src/error_codes/E0517.md index ae802245bd1..ae802245bd1 100644 --- a/src/librustc_error_codes/error_codes/E0517.md +++ b/compiler/rustc_error_codes/src/error_codes/E0517.md diff --git a/src/librustc_error_codes/error_codes/E0518.md b/compiler/rustc_error_codes/src/error_codes/E0518.md index f04329bc4e6..f04329bc4e6 100644 --- a/src/librustc_error_codes/error_codes/E0518.md +++ b/compiler/rustc_error_codes/src/error_codes/E0518.md diff --git a/src/librustc_error_codes/error_codes/E0520.md b/compiler/rustc_error_codes/src/error_codes/E0520.md index f9d7e02e5c8..f9d7e02e5c8 100644 --- a/src/librustc_error_codes/error_codes/E0520.md +++ b/compiler/rustc_error_codes/src/error_codes/E0520.md diff --git a/src/librustc_error_codes/error_codes/E0522.md b/compiler/rustc_error_codes/src/error_codes/E0522.md index 83272314a87..83272314a87 100644 --- a/src/librustc_error_codes/error_codes/E0522.md +++ b/compiler/rustc_error_codes/src/error_codes/E0522.md diff --git a/src/librustc_error_codes/error_codes/E0524.md b/compiler/rustc_error_codes/src/error_codes/E0524.md index bab241b5a95..bab241b5a95 100644 --- a/src/librustc_error_codes/error_codes/E0524.md +++ b/compiler/rustc_error_codes/src/error_codes/E0524.md diff --git a/src/librustc_error_codes/error_codes/E0525.md b/compiler/rustc_error_codes/src/error_codes/E0525.md index a769440ca1b..a769440ca1b 100644 --- a/src/librustc_error_codes/error_codes/E0525.md +++ b/compiler/rustc_error_codes/src/error_codes/E0525.md diff --git a/src/librustc_error_codes/error_codes/E0527.md b/compiler/rustc_error_codes/src/error_codes/E0527.md index 97ea3126938..97ea3126938 100644 --- a/src/librustc_error_codes/error_codes/E0527.md +++ b/compiler/rustc_error_codes/src/error_codes/E0527.md diff --git a/src/librustc_error_codes/error_codes/E0528.md b/compiler/rustc_error_codes/src/error_codes/E0528.md index 54c2c4d4e9d..54c2c4d4e9d 100644 --- a/src/librustc_error_codes/error_codes/E0528.md +++ b/compiler/rustc_error_codes/src/error_codes/E0528.md diff --git a/src/librustc_error_codes/error_codes/E0529.md b/compiler/rustc_error_codes/src/error_codes/E0529.md index 013f438ba93..013f438ba93 100644 --- a/src/librustc_error_codes/error_codes/E0529.md +++ b/compiler/rustc_error_codes/src/error_codes/E0529.md diff --git a/src/librustc_error_codes/error_codes/E0530.md b/compiler/rustc_error_codes/src/error_codes/E0530.md index 502f674fc1d..502f674fc1d 100644 --- a/src/librustc_error_codes/error_codes/E0530.md +++ b/compiler/rustc_error_codes/src/error_codes/E0530.md diff --git a/src/librustc_error_codes/error_codes/E0531.md b/compiler/rustc_error_codes/src/error_codes/E0531.md index 2814046fbdd..2814046fbdd 100644 --- a/src/librustc_error_codes/error_codes/E0531.md +++ b/compiler/rustc_error_codes/src/error_codes/E0531.md diff --git a/src/librustc_error_codes/error_codes/E0532.md b/compiler/rustc_error_codes/src/error_codes/E0532.md index 6fb315a3716..6fb315a3716 100644 --- a/src/librustc_error_codes/error_codes/E0532.md +++ b/compiler/rustc_error_codes/src/error_codes/E0532.md diff --git a/src/librustc_error_codes/error_codes/E0533.md b/compiler/rustc_error_codes/src/error_codes/E0533.md index 279d728caae..279d728caae 100644 --- a/src/librustc_error_codes/error_codes/E0533.md +++ b/compiler/rustc_error_codes/src/error_codes/E0533.md diff --git a/src/librustc_error_codes/error_codes/E0534.md b/compiler/rustc_error_codes/src/error_codes/E0534.md index 1ca9411b8d4..1ca9411b8d4 100644 --- a/src/librustc_error_codes/error_codes/E0534.md +++ b/compiler/rustc_error_codes/src/error_codes/E0534.md diff --git a/src/librustc_error_codes/error_codes/E0535.md b/compiler/rustc_error_codes/src/error_codes/E0535.md index 0cf3118b02c..0cf3118b02c 100644 --- a/src/librustc_error_codes/error_codes/E0535.md +++ b/compiler/rustc_error_codes/src/error_codes/E0535.md diff --git a/src/librustc_error_codes/error_codes/E0536.md b/compiler/rustc_error_codes/src/error_codes/E0536.md index c081a3d9cfa..c081a3d9cfa 100644 --- a/src/librustc_error_codes/error_codes/E0536.md +++ b/compiler/rustc_error_codes/src/error_codes/E0536.md diff --git a/src/librustc_error_codes/error_codes/E0537.md b/compiler/rustc_error_codes/src/error_codes/E0537.md index 123efd4f57d..123efd4f57d 100644 --- a/src/librustc_error_codes/error_codes/E0537.md +++ b/compiler/rustc_error_codes/src/error_codes/E0537.md diff --git a/src/librustc_error_codes/error_codes/E0538.md b/compiler/rustc_error_codes/src/error_codes/E0538.md index 5858771ce88..5858771ce88 100644 --- a/src/librustc_error_codes/error_codes/E0538.md +++ b/compiler/rustc_error_codes/src/error_codes/E0538.md diff --git a/src/librustc_error_codes/error_codes/E0539.md b/compiler/rustc_error_codes/src/error_codes/E0539.md index df2d7d910bb..df2d7d910bb 100644 --- a/src/librustc_error_codes/error_codes/E0539.md +++ b/compiler/rustc_error_codes/src/error_codes/E0539.md diff --git a/src/librustc_error_codes/error_codes/E0541.md b/compiler/rustc_error_codes/src/error_codes/E0541.md index 96334088fee..96334088fee 100644 --- a/src/librustc_error_codes/error_codes/E0541.md +++ b/compiler/rustc_error_codes/src/error_codes/E0541.md diff --git a/src/librustc_error_codes/error_codes/E0550.md b/compiler/rustc_error_codes/src/error_codes/E0550.md index 1487d701847..1487d701847 100644 --- a/src/librustc_error_codes/error_codes/E0550.md +++ b/compiler/rustc_error_codes/src/error_codes/E0550.md diff --git a/src/librustc_error_codes/error_codes/E0551.md b/compiler/rustc_error_codes/src/error_codes/E0551.md index 53db559a4fc..53db559a4fc 100644 --- a/src/librustc_error_codes/error_codes/E0551.md +++ b/compiler/rustc_error_codes/src/error_codes/E0551.md diff --git a/src/librustc_error_codes/error_codes/E0552.md b/compiler/rustc_error_codes/src/error_codes/E0552.md index 0fbc861fb7c..0fbc861fb7c 100644 --- a/src/librustc_error_codes/error_codes/E0552.md +++ b/compiler/rustc_error_codes/src/error_codes/E0552.md diff --git a/src/librustc_error_codes/error_codes/E0554.md b/compiler/rustc_error_codes/src/error_codes/E0554.md index e55fa4c6ede..e55fa4c6ede 100644 --- a/src/librustc_error_codes/error_codes/E0554.md +++ b/compiler/rustc_error_codes/src/error_codes/E0554.md diff --git a/src/librustc_error_codes/error_codes/E0556.md b/compiler/rustc_error_codes/src/error_codes/E0556.md index 2aac8240d29..2aac8240d29 100644 --- a/src/librustc_error_codes/error_codes/E0556.md +++ b/compiler/rustc_error_codes/src/error_codes/E0556.md diff --git a/src/librustc_error_codes/error_codes/E0557.md b/compiler/rustc_error_codes/src/error_codes/E0557.md index f330efe5933..f330efe5933 100644 --- a/src/librustc_error_codes/error_codes/E0557.md +++ b/compiler/rustc_error_codes/src/error_codes/E0557.md diff --git a/src/librustc_error_codes/error_codes/E0559.md b/compiler/rustc_error_codes/src/error_codes/E0559.md index b9f7b650892..b9f7b650892 100644 --- a/src/librustc_error_codes/error_codes/E0559.md +++ b/compiler/rustc_error_codes/src/error_codes/E0559.md diff --git a/src/librustc_error_codes/error_codes/E0560.md b/compiler/rustc_error_codes/src/error_codes/E0560.md index 7185bf38c23..7185bf38c23 100644 --- a/src/librustc_error_codes/error_codes/E0560.md +++ b/compiler/rustc_error_codes/src/error_codes/E0560.md diff --git a/src/librustc_error_codes/error_codes/E0561.md b/compiler/rustc_error_codes/src/error_codes/E0561.md index 52900189014..52900189014 100644 --- a/src/librustc_error_codes/error_codes/E0561.md +++ b/compiler/rustc_error_codes/src/error_codes/E0561.md diff --git a/src/librustc_error_codes/error_codes/E0562.md b/compiler/rustc_error_codes/src/error_codes/E0562.md index 95f038df56d..95f038df56d 100644 --- a/src/librustc_error_codes/error_codes/E0562.md +++ b/compiler/rustc_error_codes/src/error_codes/E0562.md diff --git a/src/librustc_error_codes/error_codes/E0565.md b/compiler/rustc_error_codes/src/error_codes/E0565.md index d5bba941c1d..d5bba941c1d 100644 --- a/src/librustc_error_codes/error_codes/E0565.md +++ b/compiler/rustc_error_codes/src/error_codes/E0565.md diff --git a/src/librustc_error_codes/error_codes/E0566.md b/compiler/rustc_error_codes/src/error_codes/E0566.md index 3dcd801a21a..3dcd801a21a 100644 --- a/src/librustc_error_codes/error_codes/E0566.md +++ b/compiler/rustc_error_codes/src/error_codes/E0566.md diff --git a/src/librustc_error_codes/error_codes/E0567.md b/compiler/rustc_error_codes/src/error_codes/E0567.md index 05cf8fed031..05cf8fed031 100644 --- a/src/librustc_error_codes/error_codes/E0567.md +++ b/compiler/rustc_error_codes/src/error_codes/E0567.md diff --git a/src/librustc_error_codes/error_codes/E0568.md b/compiler/rustc_error_codes/src/error_codes/E0568.md index a37381f1cbd..a37381f1cbd 100644 --- a/src/librustc_error_codes/error_codes/E0568.md +++ b/compiler/rustc_error_codes/src/error_codes/E0568.md diff --git a/src/librustc_error_codes/error_codes/E0569.md b/compiler/rustc_error_codes/src/error_codes/E0569.md index 2ca2b57ecac..2ca2b57ecac 100644 --- a/src/librustc_error_codes/error_codes/E0569.md +++ b/compiler/rustc_error_codes/src/error_codes/E0569.md diff --git a/src/librustc_error_codes/error_codes/E0570.md b/compiler/rustc_error_codes/src/error_codes/E0570.md index 355e71ffb43..355e71ffb43 100644 --- a/src/librustc_error_codes/error_codes/E0570.md +++ b/compiler/rustc_error_codes/src/error_codes/E0570.md diff --git a/src/librustc_error_codes/error_codes/E0571.md b/compiler/rustc_error_codes/src/error_codes/E0571.md index eadae05aa30..eadae05aa30 100644 --- a/src/librustc_error_codes/error_codes/E0571.md +++ b/compiler/rustc_error_codes/src/error_codes/E0571.md diff --git a/src/librustc_error_codes/error_codes/E0572.md b/compiler/rustc_error_codes/src/error_codes/E0572.md index b2660650f1b..b2660650f1b 100644 --- a/src/librustc_error_codes/error_codes/E0572.md +++ b/compiler/rustc_error_codes/src/error_codes/E0572.md diff --git a/src/librustc_error_codes/error_codes/E0573.md b/compiler/rustc_error_codes/src/error_codes/E0573.md index 6021ed0ef21..6021ed0ef21 100644 --- a/src/librustc_error_codes/error_codes/E0573.md +++ b/compiler/rustc_error_codes/src/error_codes/E0573.md diff --git a/src/librustc_error_codes/error_codes/E0574.md b/compiler/rustc_error_codes/src/error_codes/E0574.md index 8154d5b782e..8154d5b782e 100644 --- a/src/librustc_error_codes/error_codes/E0574.md +++ b/compiler/rustc_error_codes/src/error_codes/E0574.md diff --git a/src/librustc_error_codes/error_codes/E0575.md b/compiler/rustc_error_codes/src/error_codes/E0575.md index 903939a9af9..903939a9af9 100644 --- a/src/librustc_error_codes/error_codes/E0575.md +++ b/compiler/rustc_error_codes/src/error_codes/E0575.md diff --git a/src/librustc_error_codes/error_codes/E0576.md b/compiler/rustc_error_codes/src/error_codes/E0576.md index 8eead4e7e3b..8eead4e7e3b 100644 --- a/src/librustc_error_codes/error_codes/E0576.md +++ b/compiler/rustc_error_codes/src/error_codes/E0576.md diff --git a/src/librustc_error_codes/error_codes/E0577.md b/compiler/rustc_error_codes/src/error_codes/E0577.md index 1feb9c0acf3..1feb9c0acf3 100644 --- a/src/librustc_error_codes/error_codes/E0577.md +++ b/compiler/rustc_error_codes/src/error_codes/E0577.md diff --git a/src/librustc_error_codes/error_codes/E0578.md b/compiler/rustc_error_codes/src/error_codes/E0578.md index fca89757287..fca89757287 100644 --- a/src/librustc_error_codes/error_codes/E0578.md +++ b/compiler/rustc_error_codes/src/error_codes/E0578.md diff --git a/src/librustc_error_codes/error_codes/E0579.md b/compiler/rustc_error_codes/src/error_codes/E0579.md index f554242a3d4..f554242a3d4 100644 --- a/src/librustc_error_codes/error_codes/E0579.md +++ b/compiler/rustc_error_codes/src/error_codes/E0579.md diff --git a/src/librustc_error_codes/error_codes/E0580.md b/compiler/rustc_error_codes/src/error_codes/E0580.md index 260575d5de4..260575d5de4 100644 --- a/src/librustc_error_codes/error_codes/E0580.md +++ b/compiler/rustc_error_codes/src/error_codes/E0580.md diff --git a/src/librustc_error_codes/error_codes/E0581.md b/compiler/rustc_error_codes/src/error_codes/E0581.md index 89f6e3269ec..89f6e3269ec 100644 --- a/src/librustc_error_codes/error_codes/E0581.md +++ b/compiler/rustc_error_codes/src/error_codes/E0581.md diff --git a/src/librustc_error_codes/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md index e50cc60ea33..e50cc60ea33 100644 --- a/src/librustc_error_codes/error_codes/E0582.md +++ b/compiler/rustc_error_codes/src/error_codes/E0582.md diff --git a/src/librustc_error_codes/error_codes/E0583.md b/compiler/rustc_error_codes/src/error_codes/E0583.md index 701900bb0cd..701900bb0cd 100644 --- a/src/librustc_error_codes/error_codes/E0583.md +++ b/compiler/rustc_error_codes/src/error_codes/E0583.md diff --git a/src/librustc_error_codes/error_codes/E0584.md b/compiler/rustc_error_codes/src/error_codes/E0584.md index 8b00655ee78..8b00655ee78 100644 --- a/src/librustc_error_codes/error_codes/E0584.md +++ b/compiler/rustc_error_codes/src/error_codes/E0584.md diff --git a/src/librustc_error_codes/error_codes/E0585.md b/compiler/rustc_error_codes/src/error_codes/E0585.md index de27cc19d18..de27cc19d18 100644 --- a/src/librustc_error_codes/error_codes/E0585.md +++ b/compiler/rustc_error_codes/src/error_codes/E0585.md diff --git a/src/librustc_error_codes/error_codes/E0586.md b/compiler/rustc_error_codes/src/error_codes/E0586.md index bc6572ecadb..bc6572ecadb 100644 --- a/src/librustc_error_codes/error_codes/E0586.md +++ b/compiler/rustc_error_codes/src/error_codes/E0586.md diff --git a/src/librustc_error_codes/error_codes/E0587.md b/compiler/rustc_error_codes/src/error_codes/E0587.md index ee9031dc379..ee9031dc379 100644 --- a/src/librustc_error_codes/error_codes/E0587.md +++ b/compiler/rustc_error_codes/src/error_codes/E0587.md diff --git a/src/librustc_error_codes/error_codes/E0588.md b/compiler/rustc_error_codes/src/error_codes/E0588.md index 040c7a02ef4..040c7a02ef4 100644 --- a/src/librustc_error_codes/error_codes/E0588.md +++ b/compiler/rustc_error_codes/src/error_codes/E0588.md diff --git a/src/librustc_error_codes/error_codes/E0589.md b/compiler/rustc_error_codes/src/error_codes/E0589.md index 8a4f8d21725..8a4f8d21725 100644 --- a/src/librustc_error_codes/error_codes/E0589.md +++ b/compiler/rustc_error_codes/src/error_codes/E0589.md diff --git a/src/librustc_error_codes/error_codes/E0590.md b/compiler/rustc_error_codes/src/error_codes/E0590.md index 11005b8336f..11005b8336f 100644 --- a/src/librustc_error_codes/error_codes/E0590.md +++ b/compiler/rustc_error_codes/src/error_codes/E0590.md diff --git a/src/librustc_error_codes/error_codes/E0591.md b/compiler/rustc_error_codes/src/error_codes/E0591.md index 7f68815b1c2..7f68815b1c2 100644 --- a/src/librustc_error_codes/error_codes/E0591.md +++ b/compiler/rustc_error_codes/src/error_codes/E0591.md diff --git a/src/librustc_error_codes/error_codes/E0592.md b/compiler/rustc_error_codes/src/error_codes/E0592.md index 06959b5d765..06959b5d765 100644 --- a/src/librustc_error_codes/error_codes/E0592.md +++ b/compiler/rustc_error_codes/src/error_codes/E0592.md diff --git a/src/librustc_error_codes/error_codes/E0593.md b/compiler/rustc_error_codes/src/error_codes/E0593.md index 1902d73f4d0..1902d73f4d0 100644 --- a/src/librustc_error_codes/error_codes/E0593.md +++ b/compiler/rustc_error_codes/src/error_codes/E0593.md diff --git a/src/librustc_error_codes/error_codes/E0594.md b/compiler/rustc_error_codes/src/error_codes/E0594.md index ad8eb631e63..ad8eb631e63 100644 --- a/src/librustc_error_codes/error_codes/E0594.md +++ b/compiler/rustc_error_codes/src/error_codes/E0594.md diff --git a/src/librustc_error_codes/error_codes/E0595.md b/compiler/rustc_error_codes/src/error_codes/E0595.md index e6729013243..e6729013243 100644 --- a/src/librustc_error_codes/error_codes/E0595.md +++ b/compiler/rustc_error_codes/src/error_codes/E0595.md diff --git a/src/librustc_error_codes/error_codes/E0596.md b/compiler/rustc_error_codes/src/error_codes/E0596.md index 95669309b3b..95669309b3b 100644 --- a/src/librustc_error_codes/error_codes/E0596.md +++ b/compiler/rustc_error_codes/src/error_codes/E0596.md diff --git a/src/librustc_error_codes/error_codes/E0597.md b/compiler/rustc_error_codes/src/error_codes/E0597.md index 3340768fa82..3340768fa82 100644 --- a/src/librustc_error_codes/error_codes/E0597.md +++ b/compiler/rustc_error_codes/src/error_codes/E0597.md diff --git a/src/librustc_error_codes/error_codes/E0599.md b/compiler/rustc_error_codes/src/error_codes/E0599.md index 5b1590b2999..5b1590b2999 100644 --- a/src/librustc_error_codes/error_codes/E0599.md +++ b/compiler/rustc_error_codes/src/error_codes/E0599.md diff --git a/src/librustc_error_codes/error_codes/E0600.md b/compiler/rustc_error_codes/src/error_codes/E0600.md index 356006c72f3..356006c72f3 100644 --- a/src/librustc_error_codes/error_codes/E0600.md +++ b/compiler/rustc_error_codes/src/error_codes/E0600.md diff --git a/src/librustc_error_codes/error_codes/E0601.md b/compiler/rustc_error_codes/src/error_codes/E0601.md index 7194b7971d3..7194b7971d3 100644 --- a/src/librustc_error_codes/error_codes/E0601.md +++ b/compiler/rustc_error_codes/src/error_codes/E0601.md diff --git a/src/librustc_error_codes/error_codes/E0602.md b/compiler/rustc_error_codes/src/error_codes/E0602.md index dcaf251a96b..dcaf251a96b 100644 --- a/src/librustc_error_codes/error_codes/E0602.md +++ b/compiler/rustc_error_codes/src/error_codes/E0602.md diff --git a/src/librustc_error_codes/error_codes/E0603.md b/compiler/rustc_error_codes/src/error_codes/E0603.md index 69fefce3908..69fefce3908 100644 --- a/src/librustc_error_codes/error_codes/E0603.md +++ b/compiler/rustc_error_codes/src/error_codes/E0603.md diff --git a/src/librustc_error_codes/error_codes/E0604.md b/compiler/rustc_error_codes/src/error_codes/E0604.md index adbf76509ed..adbf76509ed 100644 --- a/src/librustc_error_codes/error_codes/E0604.md +++ b/compiler/rustc_error_codes/src/error_codes/E0604.md diff --git a/src/librustc_error_codes/error_codes/E0605.md b/compiler/rustc_error_codes/src/error_codes/E0605.md index f3cc65dd8cf..f3cc65dd8cf 100644 --- a/src/librustc_error_codes/error_codes/E0605.md +++ b/compiler/rustc_error_codes/src/error_codes/E0605.md diff --git a/src/librustc_error_codes/error_codes/E0606.md b/compiler/rustc_error_codes/src/error_codes/E0606.md index 06ee7497fdf..06ee7497fdf 100644 --- a/src/librustc_error_codes/error_codes/E0606.md +++ b/compiler/rustc_error_codes/src/error_codes/E0606.md diff --git a/src/librustc_error_codes/error_codes/E0607.md b/compiler/rustc_error_codes/src/error_codes/E0607.md index ea6e10105b0..ea6e10105b0 100644 --- a/src/librustc_error_codes/error_codes/E0607.md +++ b/compiler/rustc_error_codes/src/error_codes/E0607.md diff --git a/src/librustc_error_codes/error_codes/E0608.md b/compiler/rustc_error_codes/src/error_codes/E0608.md index d0ebc3a26f0..d0ebc3a26f0 100644 --- a/src/librustc_error_codes/error_codes/E0608.md +++ b/compiler/rustc_error_codes/src/error_codes/E0608.md diff --git a/src/librustc_error_codes/error_codes/E0609.md b/compiler/rustc_error_codes/src/error_codes/E0609.md index a9db34f474e..a9db34f474e 100644 --- a/src/librustc_error_codes/error_codes/E0609.md +++ b/compiler/rustc_error_codes/src/error_codes/E0609.md diff --git a/src/librustc_error_codes/error_codes/E0610.md b/compiler/rustc_error_codes/src/error_codes/E0610.md index c737bd618c3..c737bd618c3 100644 --- a/src/librustc_error_codes/error_codes/E0610.md +++ b/compiler/rustc_error_codes/src/error_codes/E0610.md diff --git a/src/librustc_error_codes/error_codes/E0614.md b/compiler/rustc_error_codes/src/error_codes/E0614.md index d0ed06ebcee..d0ed06ebcee 100644 --- a/src/librustc_error_codes/error_codes/E0614.md +++ b/compiler/rustc_error_codes/src/error_codes/E0614.md diff --git a/src/librustc_error_codes/error_codes/E0615.md b/compiler/rustc_error_codes/src/error_codes/E0615.md index f513d059625..f513d059625 100644 --- a/src/librustc_error_codes/error_codes/E0615.md +++ b/compiler/rustc_error_codes/src/error_codes/E0615.md diff --git a/src/librustc_error_codes/error_codes/E0616.md b/compiler/rustc_error_codes/src/error_codes/E0616.md index 5acbc6e44e1..5acbc6e44e1 100644 --- a/src/librustc_error_codes/error_codes/E0616.md +++ b/compiler/rustc_error_codes/src/error_codes/E0616.md diff --git a/src/librustc_error_codes/error_codes/E0617.md b/compiler/rustc_error_codes/src/error_codes/E0617.md index 61b56766c26..61b56766c26 100644 --- a/src/librustc_error_codes/error_codes/E0617.md +++ b/compiler/rustc_error_codes/src/error_codes/E0617.md diff --git a/src/librustc_error_codes/error_codes/E0618.md b/compiler/rustc_error_codes/src/error_codes/E0618.md index c8dc9040cf1..c8dc9040cf1 100644 --- a/src/librustc_error_codes/error_codes/E0618.md +++ b/compiler/rustc_error_codes/src/error_codes/E0618.md diff --git a/src/librustc_error_codes/error_codes/E0619.md b/compiler/rustc_error_codes/src/error_codes/E0619.md index f516de43095..f516de43095 100644 --- a/src/librustc_error_codes/error_codes/E0619.md +++ b/compiler/rustc_error_codes/src/error_codes/E0619.md diff --git a/src/librustc_error_codes/error_codes/E0620.md b/compiler/rustc_error_codes/src/error_codes/E0620.md index f8e442807e5..f8e442807e5 100644 --- a/src/librustc_error_codes/error_codes/E0620.md +++ b/compiler/rustc_error_codes/src/error_codes/E0620.md diff --git a/src/librustc_error_codes/error_codes/E0621.md b/compiler/rustc_error_codes/src/error_codes/E0621.md index 7c0878df25e..7c0878df25e 100644 --- a/src/librustc_error_codes/error_codes/E0621.md +++ b/compiler/rustc_error_codes/src/error_codes/E0621.md diff --git a/src/librustc_error_codes/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md index 990a2549412..990a2549412 100644 --- a/src/librustc_error_codes/error_codes/E0622.md +++ b/compiler/rustc_error_codes/src/error_codes/E0622.md diff --git a/src/librustc_error_codes/error_codes/E0623.md b/compiler/rustc_error_codes/src/error_codes/E0623.md index 1290edd0a0e..1290edd0a0e 100644 --- a/src/librustc_error_codes/error_codes/E0623.md +++ b/compiler/rustc_error_codes/src/error_codes/E0623.md diff --git a/src/librustc_error_codes/error_codes/E0624.md b/compiler/rustc_error_codes/src/error_codes/E0624.md index 0fd21c44b3d..0fd21c44b3d 100644 --- a/src/librustc_error_codes/error_codes/E0624.md +++ b/compiler/rustc_error_codes/src/error_codes/E0624.md diff --git a/src/librustc_error_codes/error_codes/E0626.md b/compiler/rustc_error_codes/src/error_codes/E0626.md index cc6e03d1ca7..cc6e03d1ca7 100644 --- a/src/librustc_error_codes/error_codes/E0626.md +++ b/compiler/rustc_error_codes/src/error_codes/E0626.md diff --git a/src/librustc_error_codes/error_codes/E0627.md b/compiler/rustc_error_codes/src/error_codes/E0627.md index 21358e1e567..21358e1e567 100644 --- a/src/librustc_error_codes/error_codes/E0627.md +++ b/compiler/rustc_error_codes/src/error_codes/E0627.md diff --git a/src/librustc_error_codes/error_codes/E0628.md b/compiler/rustc_error_codes/src/error_codes/E0628.md index 40040c9a56a..40040c9a56a 100644 --- a/src/librustc_error_codes/error_codes/E0628.md +++ b/compiler/rustc_error_codes/src/error_codes/E0628.md diff --git a/src/librustc_error_codes/error_codes/E0631.md b/compiler/rustc_error_codes/src/error_codes/E0631.md index 6188d5f61a7..6188d5f61a7 100644 --- a/src/librustc_error_codes/error_codes/E0631.md +++ b/compiler/rustc_error_codes/src/error_codes/E0631.md diff --git a/src/librustc_error_codes/error_codes/E0633.md b/compiler/rustc_error_codes/src/error_codes/E0633.md index 7f488cde664..7f488cde664 100644 --- a/src/librustc_error_codes/error_codes/E0633.md +++ b/compiler/rustc_error_codes/src/error_codes/E0633.md diff --git a/src/librustc_error_codes/error_codes/E0634.md b/compiler/rustc_error_codes/src/error_codes/E0634.md index 0c4ed2596e2..0c4ed2596e2 100644 --- a/src/librustc_error_codes/error_codes/E0634.md +++ b/compiler/rustc_error_codes/src/error_codes/E0634.md diff --git a/src/librustc_error_codes/error_codes/E0635.md b/compiler/rustc_error_codes/src/error_codes/E0635.md index a39d2be4f8f..a39d2be4f8f 100644 --- a/src/librustc_error_codes/error_codes/E0635.md +++ b/compiler/rustc_error_codes/src/error_codes/E0635.md diff --git a/src/librustc_error_codes/error_codes/E0636.md b/compiler/rustc_error_codes/src/error_codes/E0636.md index 57cf72db556..57cf72db556 100644 --- a/src/librustc_error_codes/error_codes/E0636.md +++ b/compiler/rustc_error_codes/src/error_codes/E0636.md diff --git a/src/librustc_error_codes/error_codes/E0637.md b/compiler/rustc_error_codes/src/error_codes/E0637.md index d9068950bdf..d9068950bdf 100644 --- a/src/librustc_error_codes/error_codes/E0637.md +++ b/compiler/rustc_error_codes/src/error_codes/E0637.md diff --git a/src/librustc_error_codes/error_codes/E0638.md b/compiler/rustc_error_codes/src/error_codes/E0638.md index 14cd31502b6..14cd31502b6 100644 --- a/src/librustc_error_codes/error_codes/E0638.md +++ b/compiler/rustc_error_codes/src/error_codes/E0638.md diff --git a/src/librustc_error_codes/error_codes/E0639.md b/compiler/rustc_error_codes/src/error_codes/E0639.md index 4646e37fb75..4646e37fb75 100644 --- a/src/librustc_error_codes/error_codes/E0639.md +++ b/compiler/rustc_error_codes/src/error_codes/E0639.md diff --git a/src/librustc_error_codes/error_codes/E0641.md b/compiler/rustc_error_codes/src/error_codes/E0641.md index 5848e9b5c05..5848e9b5c05 100644 --- a/src/librustc_error_codes/error_codes/E0641.md +++ b/compiler/rustc_error_codes/src/error_codes/E0641.md diff --git a/src/librustc_error_codes/error_codes/E0642.md b/compiler/rustc_error_codes/src/error_codes/E0642.md index c790aa154bd..c790aa154bd 100644 --- a/src/librustc_error_codes/error_codes/E0642.md +++ b/compiler/rustc_error_codes/src/error_codes/E0642.md diff --git a/src/librustc_error_codes/error_codes/E0643.md b/compiler/rustc_error_codes/src/error_codes/E0643.md index 53919607dfb..53919607dfb 100644 --- a/src/librustc_error_codes/error_codes/E0643.md +++ b/compiler/rustc_error_codes/src/error_codes/E0643.md diff --git a/src/librustc_error_codes/error_codes/E0644.md b/compiler/rustc_error_codes/src/error_codes/E0644.md index 8c68da3b2f3..8c68da3b2f3 100644 --- a/src/librustc_error_codes/error_codes/E0644.md +++ b/compiler/rustc_error_codes/src/error_codes/E0644.md diff --git a/src/librustc_error_codes/error_codes/E0646.md b/compiler/rustc_error_codes/src/error_codes/E0646.md index 1e9ec7d4380..1e9ec7d4380 100644 --- a/src/librustc_error_codes/error_codes/E0646.md +++ b/compiler/rustc_error_codes/src/error_codes/E0646.md diff --git a/src/librustc_error_codes/error_codes/E0647.md b/compiler/rustc_error_codes/src/error_codes/E0647.md index 8ca6e777f30..8ca6e777f30 100644 --- a/src/librustc_error_codes/error_codes/E0647.md +++ b/compiler/rustc_error_codes/src/error_codes/E0647.md diff --git a/src/librustc_error_codes/error_codes/E0648.md b/compiler/rustc_error_codes/src/error_codes/E0648.md index d99dc19503d..d99dc19503d 100644 --- a/src/librustc_error_codes/error_codes/E0648.md +++ b/compiler/rustc_error_codes/src/error_codes/E0648.md diff --git a/src/librustc_error_codes/error_codes/E0657.md b/compiler/rustc_error_codes/src/error_codes/E0657.md index 7fe48c51147..7fe48c51147 100644 --- a/src/librustc_error_codes/error_codes/E0657.md +++ b/compiler/rustc_error_codes/src/error_codes/E0657.md diff --git a/src/librustc_error_codes/error_codes/E0658.md b/compiler/rustc_error_codes/src/error_codes/E0658.md index d821b9027f1..d821b9027f1 100644 --- a/src/librustc_error_codes/error_codes/E0658.md +++ b/compiler/rustc_error_codes/src/error_codes/E0658.md diff --git a/src/librustc_error_codes/error_codes/E0659.md b/compiler/rustc_error_codes/src/error_codes/E0659.md index e2c7e25cc84..e2c7e25cc84 100644 --- a/src/librustc_error_codes/error_codes/E0659.md +++ b/compiler/rustc_error_codes/src/error_codes/E0659.md diff --git a/src/librustc_error_codes/error_codes/E0660.md b/compiler/rustc_error_codes/src/error_codes/E0660.md index fccd1b96f60..fccd1b96f60 100644 --- a/src/librustc_error_codes/error_codes/E0660.md +++ b/compiler/rustc_error_codes/src/error_codes/E0660.md diff --git a/src/librustc_error_codes/error_codes/E0661.md b/compiler/rustc_error_codes/src/error_codes/E0661.md index f1debee7a18..f1debee7a18 100644 --- a/src/librustc_error_codes/error_codes/E0661.md +++ b/compiler/rustc_error_codes/src/error_codes/E0661.md diff --git a/src/librustc_error_codes/error_codes/E0662.md b/compiler/rustc_error_codes/src/error_codes/E0662.md index d4765f078b0..d4765f078b0 100644 --- a/src/librustc_error_codes/error_codes/E0662.md +++ b/compiler/rustc_error_codes/src/error_codes/E0662.md diff --git a/src/librustc_error_codes/error_codes/E0663.md b/compiler/rustc_error_codes/src/error_codes/E0663.md index d5a85b275db..d5a85b275db 100644 --- a/src/librustc_error_codes/error_codes/E0663.md +++ b/compiler/rustc_error_codes/src/error_codes/E0663.md diff --git a/src/librustc_error_codes/error_codes/E0664.md b/compiler/rustc_error_codes/src/error_codes/E0664.md index ce9c9491df3..ce9c9491df3 100644 --- a/src/librustc_error_codes/error_codes/E0664.md +++ b/compiler/rustc_error_codes/src/error_codes/E0664.md diff --git a/src/librustc_error_codes/error_codes/E0665.md b/compiler/rustc_error_codes/src/error_codes/E0665.md index a15f4021c71..a15f4021c71 100644 --- a/src/librustc_error_codes/error_codes/E0665.md +++ b/compiler/rustc_error_codes/src/error_codes/E0665.md diff --git a/src/librustc_error_codes/error_codes/E0666.md b/compiler/rustc_error_codes/src/error_codes/E0666.md index 1a0dc5a5229..1a0dc5a5229 100644 --- a/src/librustc_error_codes/error_codes/E0666.md +++ b/compiler/rustc_error_codes/src/error_codes/E0666.md diff --git a/src/librustc_error_codes/error_codes/E0668.md b/compiler/rustc_error_codes/src/error_codes/E0668.md index b6fedfe53fc..b6fedfe53fc 100644 --- a/src/librustc_error_codes/error_codes/E0668.md +++ b/compiler/rustc_error_codes/src/error_codes/E0668.md diff --git a/src/librustc_error_codes/error_codes/E0669.md b/compiler/rustc_error_codes/src/error_codes/E0669.md index f078c441b34..f078c441b34 100644 --- a/src/librustc_error_codes/error_codes/E0669.md +++ b/compiler/rustc_error_codes/src/error_codes/E0669.md diff --git a/src/librustc_error_codes/error_codes/E0670.md b/compiler/rustc_error_codes/src/error_codes/E0670.md index 74c1af06cf4..74c1af06cf4 100644 --- a/src/librustc_error_codes/error_codes/E0670.md +++ b/compiler/rustc_error_codes/src/error_codes/E0670.md diff --git a/src/librustc_error_codes/error_codes/E0671.md b/compiler/rustc_error_codes/src/error_codes/E0671.md index a993ce826a7..a993ce826a7 100644 --- a/src/librustc_error_codes/error_codes/E0671.md +++ b/compiler/rustc_error_codes/src/error_codes/E0671.md diff --git a/src/librustc_error_codes/error_codes/E0687.md b/compiler/rustc_error_codes/src/error_codes/E0687.md index 67b7db2d31f..67b7db2d31f 100644 --- a/src/librustc_error_codes/error_codes/E0687.md +++ b/compiler/rustc_error_codes/src/error_codes/E0687.md diff --git a/src/librustc_error_codes/error_codes/E0688.md b/compiler/rustc_error_codes/src/error_codes/E0688.md index db50f490208..db50f490208 100644 --- a/src/librustc_error_codes/error_codes/E0688.md +++ b/compiler/rustc_error_codes/src/error_codes/E0688.md diff --git a/src/librustc_error_codes/error_codes/E0689.md b/compiler/rustc_error_codes/src/error_codes/E0689.md index a680a204211..a680a204211 100644 --- a/src/librustc_error_codes/error_codes/E0689.md +++ b/compiler/rustc_error_codes/src/error_codes/E0689.md diff --git a/src/librustc_error_codes/error_codes/E0690.md b/compiler/rustc_error_codes/src/error_codes/E0690.md index 1673456580a..1673456580a 100644 --- a/src/librustc_error_codes/error_codes/E0690.md +++ b/compiler/rustc_error_codes/src/error_codes/E0690.md diff --git a/src/librustc_error_codes/error_codes/E0691.md b/compiler/rustc_error_codes/src/error_codes/E0691.md index 60060cacbd6..60060cacbd6 100644 --- a/src/librustc_error_codes/error_codes/E0691.md +++ b/compiler/rustc_error_codes/src/error_codes/E0691.md diff --git a/src/librustc_error_codes/error_codes/E0692.md b/compiler/rustc_error_codes/src/error_codes/E0692.md index 596cb1e777e..596cb1e777e 100644 --- a/src/librustc_error_codes/error_codes/E0692.md +++ b/compiler/rustc_error_codes/src/error_codes/E0692.md diff --git a/src/librustc_error_codes/error_codes/E0693.md b/compiler/rustc_error_codes/src/error_codes/E0693.md index 43e9d17979e..43e9d17979e 100644 --- a/src/librustc_error_codes/error_codes/E0693.md +++ b/compiler/rustc_error_codes/src/error_codes/E0693.md diff --git a/src/librustc_error_codes/error_codes/E0695.md b/compiler/rustc_error_codes/src/error_codes/E0695.md index 5013e83ca03..5013e83ca03 100644 --- a/src/librustc_error_codes/error_codes/E0695.md +++ b/compiler/rustc_error_codes/src/error_codes/E0695.md diff --git a/src/librustc_error_codes/error_codes/E0696.md b/compiler/rustc_error_codes/src/error_codes/E0696.md index fc32d1cc5f7..fc32d1cc5f7 100644 --- a/src/librustc_error_codes/error_codes/E0696.md +++ b/compiler/rustc_error_codes/src/error_codes/E0696.md diff --git a/src/librustc_error_codes/error_codes/E0697.md b/compiler/rustc_error_codes/src/error_codes/E0697.md index ab63d2e73f7..ab63d2e73f7 100644 --- a/src/librustc_error_codes/error_codes/E0697.md +++ b/compiler/rustc_error_codes/src/error_codes/E0697.md diff --git a/src/librustc_error_codes/error_codes/E0698.md b/compiler/rustc_error_codes/src/error_codes/E0698.md index 3ba992a8476..3ba992a8476 100644 --- a/src/librustc_error_codes/error_codes/E0698.md +++ b/compiler/rustc_error_codes/src/error_codes/E0698.md diff --git a/src/librustc_error_codes/error_codes/E0699.md b/compiler/rustc_error_codes/src/error_codes/E0699.md index 454d2507e5e..454d2507e5e 100644 --- a/src/librustc_error_codes/error_codes/E0699.md +++ b/compiler/rustc_error_codes/src/error_codes/E0699.md diff --git a/src/librustc_error_codes/error_codes/E0700.md b/compiler/rustc_error_codes/src/error_codes/E0700.md index b1eb8b66ad6..b1eb8b66ad6 100644 --- a/src/librustc_error_codes/error_codes/E0700.md +++ b/compiler/rustc_error_codes/src/error_codes/E0700.md diff --git a/src/librustc_error_codes/error_codes/E0701.md b/compiler/rustc_error_codes/src/error_codes/E0701.md index 4965e643105..4965e643105 100644 --- a/src/librustc_error_codes/error_codes/E0701.md +++ b/compiler/rustc_error_codes/src/error_codes/E0701.md diff --git a/src/librustc_error_codes/error_codes/E0703.md b/compiler/rustc_error_codes/src/error_codes/E0703.md index b42677d52cb..b42677d52cb 100644 --- a/src/librustc_error_codes/error_codes/E0703.md +++ b/compiler/rustc_error_codes/src/error_codes/E0703.md diff --git a/src/librustc_error_codes/error_codes/E0704.md b/compiler/rustc_error_codes/src/error_codes/E0704.md index c22b274fb22..c22b274fb22 100644 --- a/src/librustc_error_codes/error_codes/E0704.md +++ b/compiler/rustc_error_codes/src/error_codes/E0704.md diff --git a/src/librustc_error_codes/error_codes/E0705.md b/compiler/rustc_error_codes/src/error_codes/E0705.md index 1edd47de4cb..1edd47de4cb 100644 --- a/src/librustc_error_codes/error_codes/E0705.md +++ b/compiler/rustc_error_codes/src/error_codes/E0705.md diff --git a/src/librustc_error_codes/error_codes/E0706.md b/compiler/rustc_error_codes/src/error_codes/E0706.md index d379b8a2384..d379b8a2384 100644 --- a/src/librustc_error_codes/error_codes/E0706.md +++ b/compiler/rustc_error_codes/src/error_codes/E0706.md diff --git a/src/librustc_error_codes/error_codes/E0708.md b/compiler/rustc_error_codes/src/error_codes/E0708.md index 9287fc803d1..9287fc803d1 100644 --- a/src/librustc_error_codes/error_codes/E0708.md +++ b/compiler/rustc_error_codes/src/error_codes/E0708.md diff --git a/src/librustc_error_codes/error_codes/E0710.md b/compiler/rustc_error_codes/src/error_codes/E0710.md index b7037ea611b..b7037ea611b 100644 --- a/src/librustc_error_codes/error_codes/E0710.md +++ b/compiler/rustc_error_codes/src/error_codes/E0710.md diff --git a/src/librustc_error_codes/error_codes/E0712.md b/compiler/rustc_error_codes/src/error_codes/E0712.md index 7e09210e787..7e09210e787 100644 --- a/src/librustc_error_codes/error_codes/E0712.md +++ b/compiler/rustc_error_codes/src/error_codes/E0712.md diff --git a/src/librustc_error_codes/error_codes/E0713.md b/compiler/rustc_error_codes/src/error_codes/E0713.md index 9361046943f..9361046943f 100644 --- a/src/librustc_error_codes/error_codes/E0713.md +++ b/compiler/rustc_error_codes/src/error_codes/E0713.md diff --git a/src/librustc_error_codes/error_codes/E0714.md b/compiler/rustc_error_codes/src/error_codes/E0714.md index 45d1cafa690..45d1cafa690 100644 --- a/src/librustc_error_codes/error_codes/E0714.md +++ b/compiler/rustc_error_codes/src/error_codes/E0714.md diff --git a/src/librustc_error_codes/error_codes/E0715.md b/compiler/rustc_error_codes/src/error_codes/E0715.md index b27702b3c26..b27702b3c26 100644 --- a/src/librustc_error_codes/error_codes/E0715.md +++ b/compiler/rustc_error_codes/src/error_codes/E0715.md diff --git a/src/librustc_error_codes/error_codes/E0716.md b/compiler/rustc_error_codes/src/error_codes/E0716.md index c6d0337ddda..c6d0337ddda 100644 --- a/src/librustc_error_codes/error_codes/E0716.md +++ b/compiler/rustc_error_codes/src/error_codes/E0716.md diff --git a/src/librustc_error_codes/error_codes/E0718.md b/compiler/rustc_error_codes/src/error_codes/E0718.md index 1fe62ecf1f4..1fe62ecf1f4 100644 --- a/src/librustc_error_codes/error_codes/E0718.md +++ b/compiler/rustc_error_codes/src/error_codes/E0718.md diff --git a/src/librustc_error_codes/error_codes/E0719.md b/compiler/rustc_error_codes/src/error_codes/E0719.md index 057a0b1645c..057a0b1645c 100644 --- a/src/librustc_error_codes/error_codes/E0719.md +++ b/compiler/rustc_error_codes/src/error_codes/E0719.md diff --git a/src/librustc_error_codes/error_codes/E0720.md b/compiler/rustc_error_codes/src/error_codes/E0720.md index 40dfa484d3f..40dfa484d3f 100644 --- a/src/librustc_error_codes/error_codes/E0720.md +++ b/compiler/rustc_error_codes/src/error_codes/E0720.md diff --git a/src/librustc_error_codes/error_codes/E0723.md b/compiler/rustc_error_codes/src/error_codes/E0723.md index 95d47ab21cb..95d47ab21cb 100644 --- a/src/librustc_error_codes/error_codes/E0723.md +++ b/compiler/rustc_error_codes/src/error_codes/E0723.md diff --git a/src/librustc_error_codes/error_codes/E0724.md b/compiler/rustc_error_codes/src/error_codes/E0724.md index e8f84d0fc7d..e8f84d0fc7d 100644 --- a/src/librustc_error_codes/error_codes/E0724.md +++ b/compiler/rustc_error_codes/src/error_codes/E0724.md diff --git a/src/librustc_error_codes/error_codes/E0725.md b/compiler/rustc_error_codes/src/error_codes/E0725.md index 9bd321e5f82..9bd321e5f82 100644 --- a/src/librustc_error_codes/error_codes/E0725.md +++ b/compiler/rustc_error_codes/src/error_codes/E0725.md diff --git a/src/librustc_error_codes/error_codes/E0727.md b/compiler/rustc_error_codes/src/error_codes/E0727.md index 386daea0c57..386daea0c57 100644 --- a/src/librustc_error_codes/error_codes/E0727.md +++ b/compiler/rustc_error_codes/src/error_codes/E0727.md diff --git a/src/librustc_error_codes/error_codes/E0728.md b/compiler/rustc_error_codes/src/error_codes/E0728.md index f4968a4f00e..f4968a4f00e 100644 --- a/src/librustc_error_codes/error_codes/E0728.md +++ b/compiler/rustc_error_codes/src/error_codes/E0728.md diff --git a/src/librustc_error_codes/error_codes/E0729.md b/compiler/rustc_error_codes/src/error_codes/E0729.md index 74f89080b91..74f89080b91 100644 --- a/src/librustc_error_codes/error_codes/E0729.md +++ b/compiler/rustc_error_codes/src/error_codes/E0729.md diff --git a/src/librustc_error_codes/error_codes/E0730.md b/compiler/rustc_error_codes/src/error_codes/E0730.md index 016b3f38aa3..016b3f38aa3 100644 --- a/src/librustc_error_codes/error_codes/E0730.md +++ b/compiler/rustc_error_codes/src/error_codes/E0730.md diff --git a/src/librustc_error_codes/error_codes/E0731.md b/compiler/rustc_error_codes/src/error_codes/E0731.md index 096c053fe83..096c053fe83 100644 --- a/src/librustc_error_codes/error_codes/E0731.md +++ b/compiler/rustc_error_codes/src/error_codes/E0731.md diff --git a/src/librustc_error_codes/error_codes/E0732.md b/compiler/rustc_error_codes/src/error_codes/E0732.md index 7347e6654c5..7347e6654c5 100644 --- a/src/librustc_error_codes/error_codes/E0732.md +++ b/compiler/rustc_error_codes/src/error_codes/E0732.md diff --git a/src/librustc_error_codes/error_codes/E0733.md b/compiler/rustc_error_codes/src/error_codes/E0733.md index 051b75148e5..051b75148e5 100644 --- a/src/librustc_error_codes/error_codes/E0733.md +++ b/compiler/rustc_error_codes/src/error_codes/E0733.md diff --git a/src/librustc_error_codes/error_codes/E0734.md b/compiler/rustc_error_codes/src/error_codes/E0734.md index 4b8e89a7060..4b8e89a7060 100644 --- a/src/librustc_error_codes/error_codes/E0734.md +++ b/compiler/rustc_error_codes/src/error_codes/E0734.md diff --git a/src/librustc_error_codes/error_codes/E0735.md b/compiler/rustc_error_codes/src/error_codes/E0735.md index e8268a5836c..e8268a5836c 100644 --- a/src/librustc_error_codes/error_codes/E0735.md +++ b/compiler/rustc_error_codes/src/error_codes/E0735.md diff --git a/src/librustc_error_codes/error_codes/E0736.md b/compiler/rustc_error_codes/src/error_codes/E0736.md index 0f3d41ba66d..0f3d41ba66d 100644 --- a/src/librustc_error_codes/error_codes/E0736.md +++ b/compiler/rustc_error_codes/src/error_codes/E0736.md diff --git a/src/librustc_error_codes/error_codes/E0737.md b/compiler/rustc_error_codes/src/error_codes/E0737.md index ab5e60692b4..ab5e60692b4 100644 --- a/src/librustc_error_codes/error_codes/E0737.md +++ b/compiler/rustc_error_codes/src/error_codes/E0737.md diff --git a/src/librustc_error_codes/error_codes/E0739.md b/compiler/rustc_error_codes/src/error_codes/E0739.md index 8d9039bef93..8d9039bef93 100644 --- a/src/librustc_error_codes/error_codes/E0739.md +++ b/compiler/rustc_error_codes/src/error_codes/E0739.md diff --git a/src/librustc_error_codes/error_codes/E0740.md b/compiler/rustc_error_codes/src/error_codes/E0740.md index 6240099a99f..6240099a99f 100644 --- a/src/librustc_error_codes/error_codes/E0740.md +++ b/compiler/rustc_error_codes/src/error_codes/E0740.md diff --git a/src/librustc_error_codes/error_codes/E0741.md b/compiler/rustc_error_codes/src/error_codes/E0741.md index 91379bfe05c..91379bfe05c 100644 --- a/src/librustc_error_codes/error_codes/E0741.md +++ b/compiler/rustc_error_codes/src/error_codes/E0741.md diff --git a/src/librustc_error_codes/error_codes/E0742.md b/compiler/rustc_error_codes/src/error_codes/E0742.md index fed9f1f4cee..fed9f1f4cee 100644 --- a/src/librustc_error_codes/error_codes/E0742.md +++ b/compiler/rustc_error_codes/src/error_codes/E0742.md diff --git a/src/librustc_error_codes/error_codes/E0743.md b/compiler/rustc_error_codes/src/error_codes/E0743.md index ddd3136df0c..ddd3136df0c 100644 --- a/src/librustc_error_codes/error_codes/E0743.md +++ b/compiler/rustc_error_codes/src/error_codes/E0743.md diff --git a/src/librustc_error_codes/error_codes/E0744.md b/compiler/rustc_error_codes/src/error_codes/E0744.md index 14cff3613e0..14cff3613e0 100644 --- a/src/librustc_error_codes/error_codes/E0744.md +++ b/compiler/rustc_error_codes/src/error_codes/E0744.md diff --git a/src/librustc_error_codes/error_codes/E0745.md b/compiler/rustc_error_codes/src/error_codes/E0745.md index 23ee7af30f4..23ee7af30f4 100644 --- a/src/librustc_error_codes/error_codes/E0745.md +++ b/compiler/rustc_error_codes/src/error_codes/E0745.md diff --git a/src/librustc_error_codes/error_codes/E0746.md b/compiler/rustc_error_codes/src/error_codes/E0746.md index 90755d47f67..90755d47f67 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/compiler/rustc_error_codes/src/error_codes/E0746.md diff --git a/src/librustc_error_codes/error_codes/E0747.md b/compiler/rustc_error_codes/src/error_codes/E0747.md index caf7e0fba07..caf7e0fba07 100644 --- a/src/librustc_error_codes/error_codes/E0747.md +++ b/compiler/rustc_error_codes/src/error_codes/E0747.md diff --git a/src/librustc_error_codes/error_codes/E0748.md b/compiler/rustc_error_codes/src/error_codes/E0748.md index 69f1c026125..69f1c026125 100644 --- a/src/librustc_error_codes/error_codes/E0748.md +++ b/compiler/rustc_error_codes/src/error_codes/E0748.md diff --git a/src/librustc_error_codes/error_codes/E0749.md b/compiler/rustc_error_codes/src/error_codes/E0749.md index dfe90ae89e4..dfe90ae89e4 100644 --- a/src/librustc_error_codes/error_codes/E0749.md +++ b/compiler/rustc_error_codes/src/error_codes/E0749.md diff --git a/src/librustc_error_codes/error_codes/E0750.md b/compiler/rustc_error_codes/src/error_codes/E0750.md index 905e852f8d5..905e852f8d5 100644 --- a/src/librustc_error_codes/error_codes/E0750.md +++ b/compiler/rustc_error_codes/src/error_codes/E0750.md diff --git a/src/librustc_error_codes/error_codes/E0751.md b/compiler/rustc_error_codes/src/error_codes/E0751.md index 8794f7868f3..8794f7868f3 100644 --- a/src/librustc_error_codes/error_codes/E0751.md +++ b/compiler/rustc_error_codes/src/error_codes/E0751.md diff --git a/src/librustc_error_codes/error_codes/E0752.md b/compiler/rustc_error_codes/src/error_codes/E0752.md index 9736da80c2b..9736da80c2b 100644 --- a/src/librustc_error_codes/error_codes/E0752.md +++ b/compiler/rustc_error_codes/src/error_codes/E0752.md diff --git a/src/librustc_error_codes/error_codes/E0753.md b/compiler/rustc_error_codes/src/error_codes/E0753.md index a69da964aee..a69da964aee 100644 --- a/src/librustc_error_codes/error_codes/E0753.md +++ b/compiler/rustc_error_codes/src/error_codes/E0753.md diff --git a/src/librustc_error_codes/error_codes/E0754.md b/compiler/rustc_error_codes/src/error_codes/E0754.md index 57620bcd65c..57620bcd65c 100644 --- a/src/librustc_error_codes/error_codes/E0754.md +++ b/compiler/rustc_error_codes/src/error_codes/E0754.md diff --git a/src/librustc_error_codes/error_codes/E0758.md b/compiler/rustc_error_codes/src/error_codes/E0758.md index ddca4b3d75f..ddca4b3d75f 100644 --- a/src/librustc_error_codes/error_codes/E0758.md +++ b/compiler/rustc_error_codes/src/error_codes/E0758.md diff --git a/src/librustc_error_codes/error_codes/E0759.md b/compiler/rustc_error_codes/src/error_codes/E0759.md index 6d525310f75..6d525310f75 100644 --- a/src/librustc_error_codes/error_codes/E0759.md +++ b/compiler/rustc_error_codes/src/error_codes/E0759.md diff --git a/src/librustc_error_codes/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md index e1dcfefebcd..e1dcfefebcd 100644 --- a/src/librustc_error_codes/error_codes/E0760.md +++ b/compiler/rustc_error_codes/src/error_codes/E0760.md diff --git a/src/librustc_error_codes/error_codes/E0761.md b/compiler/rustc_error_codes/src/error_codes/E0761.md index e112674fbcc..e112674fbcc 100644 --- a/src/librustc_error_codes/error_codes/E0761.md +++ b/compiler/rustc_error_codes/src/error_codes/E0761.md diff --git a/src/librustc_error_codes/error_codes/E0762.md b/compiler/rustc_error_codes/src/error_codes/E0762.md index b01ded4a866..b01ded4a866 100644 --- a/src/librustc_error_codes/error_codes/E0762.md +++ b/compiler/rustc_error_codes/src/error_codes/E0762.md diff --git a/src/librustc_error_codes/error_codes/E0763.md b/compiler/rustc_error_codes/src/error_codes/E0763.md index 095b779f3e7..095b779f3e7 100644 --- a/src/librustc_error_codes/error_codes/E0763.md +++ b/compiler/rustc_error_codes/src/error_codes/E0763.md diff --git a/src/librustc_error_codes/error_codes/E0764.md b/compiler/rustc_error_codes/src/error_codes/E0764.md index e9061f988ac..0a2e2290e77 100644 --- a/src/librustc_error_codes/error_codes/E0764.md +++ b/compiler/rustc_error_codes/src/error_codes/E0764.md @@ -1,12 +1,4 @@ -Mutable references (`&mut`) can only be used in constant functions, not statics -or constants. This limitation exists to prevent the creation of constants that -have a mutable reference in their final value. If you had a constant of `&mut -i32` type, you could modify the value through that reference, making the -constant essentially mutable. While there could be a more fine-grained scheme -in the future that allows mutable references if they are not "leaked" to the -final value, a more conservative approach was chosen for now. `const fn` do not -have this problem, as the borrow checker will prevent the `const fn` from -returning new mutable references. +A mutable reference was used in a constant. Erroneous code example: @@ -19,6 +11,18 @@ fn main() { } ``` +Mutable references (`&mut`) can only be used in constant functions, not statics +or constants. This limitation exists to prevent the creation of constants that +have a mutable reference in their final value. If you had a constant of +`&mut i32` type, you could modify the value through that reference, making the +constant essentially mutable. + +While there could be a more fine-grained scheme in the future that allows +mutable references if they are not "leaked" to the final value, a more +conservative approach was chosen for now. `const fn` do not have this problem, +as the borrow checker will prevent the `const fn` from returning new mutable +references. + Remember: you cannot use a function call inside a constant or static. However, you can totally use it in constant functions: diff --git a/src/librustc_error_codes/error_codes/E0765.md b/compiler/rustc_error_codes/src/error_codes/E0765.md index 456e3f3e9e4..456e3f3e9e4 100644 --- a/src/librustc_error_codes/error_codes/E0765.md +++ b/compiler/rustc_error_codes/src/error_codes/E0765.md diff --git a/src/librustc_error_codes/error_codes/E0766.md b/compiler/rustc_error_codes/src/error_codes/E0766.md index 4e775df2cac..4e775df2cac 100644 --- a/src/librustc_error_codes/error_codes/E0766.md +++ b/compiler/rustc_error_codes/src/error_codes/E0766.md diff --git a/src/librustc_error_codes/error_codes/E0767.md b/compiler/rustc_error_codes/src/error_codes/E0767.md index 679fe7e41e9..679fe7e41e9 100644 --- a/src/librustc_error_codes/error_codes/E0767.md +++ b/compiler/rustc_error_codes/src/error_codes/E0767.md diff --git a/src/librustc_error_codes/error_codes/E0768.md b/compiler/rustc_error_codes/src/error_codes/E0768.md index 24169ef512e..24169ef512e 100644 --- a/src/librustc_error_codes/error_codes/E0768.md +++ b/compiler/rustc_error_codes/src/error_codes/E0768.md diff --git a/src/librustc_error_codes/error_codes/E0769.md b/compiler/rustc_error_codes/src/error_codes/E0769.md index d1995be9899..4a3b674b058 100644 --- a/src/librustc_error_codes/error_codes/E0769.md +++ b/compiler/rustc_error_codes/src/error_codes/E0769.md @@ -1,5 +1,5 @@ -A tuple struct or tuple variant was used in a pattern as if it were a -struct or struct variant. +A tuple struct or tuple variant was used in a pattern as if it were a struct or +struct variant. Erroneous code example: @@ -7,9 +7,13 @@ Erroneous code example: enum E { A(i32), } + let e = E::A(42); + match e { - E::A { number } => println!("{}", x), + E::A { number } => { // error! + println!("{}", number); + } } ``` @@ -21,12 +25,14 @@ To fix this error, you can use the tuple pattern: # } # let e = E::A(42); match e { - E::A(number) => println!("{}", number), + E::A(number) => { // ok! + println!("{}", number); + } } ``` -Alternatively, you can also use the struct pattern by using the correct -field names and binding them to new identifiers: +Alternatively, you can also use the struct pattern by using the correct field +names and binding them to new identifiers: ``` # enum E { @@ -34,6 +40,8 @@ field names and binding them to new identifiers: # } # let e = E::A(42); match e { - E::A { 0: number } => println!("{}", number), + E::A { 0: number } => { // ok! + println!("{}", number); + } } ``` diff --git a/src/librustc_error_codes/error_codes/E0770.md b/compiler/rustc_error_codes/src/error_codes/E0770.md index 278bf9b907b..278bf9b907b 100644 --- a/src/librustc_error_codes/error_codes/E0770.md +++ b/compiler/rustc_error_codes/src/error_codes/E0770.md diff --git a/src/librustc_error_codes/error_codes/E0771.md b/compiler/rustc_error_codes/src/error_codes/E0771.md index 824a955f6b3..824a955f6b3 100644 --- a/src/librustc_error_codes/error_codes/E0771.md +++ b/compiler/rustc_error_codes/src/error_codes/E0771.md diff --git a/compiler/rustc_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md new file mode 100644 index 00000000000..b19a58bf33d --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0773.md @@ -0,0 +1,38 @@ +A builtin-macro was defined more than once. + +Erroneous code example: + +```compile_fail,E0773 +#![feature(decl_macro)] +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +pub macro test($item:item) { + /* compiler built-in */ +} + +mod inner { + #[rustc_builtin_macro] + pub macro test($item:item) { + /* compiler built-in */ + } +} +``` + +To fix the issue, remove the duplicate declaration: + +``` +#![feature(decl_macro)] +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +pub macro test($item:item) { + /* compiler built-in */ +} +``` + +In very rare edge cases, this may happen when loading `core` or `std` twice, +once with `check` metadata and once with `build` metadata. +For more information, see [#75176]. + +[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468 diff --git a/src/librustc_error_codes/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 4353a294cc3..4353a294cc3 100644 --- a/src/librustc_error_codes/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs diff --git a/src/librustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 7c794bcd98f..e4dbb8db381 100644 --- a/src/librustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -5,16 +5,14 @@ version = "0.0.0" edition = "2018" [lib] -name = "rustc_errors" -path = "lib.rs" doctest = false [dependencies] tracing = "0.1" -rustc_serialize = { path = "../librustc_serialize" } -rustc_span = { path = "../librustc_span" } -rustc_macros = { path = "../librustc_macros" } -rustc_data_structures = { path = "../librustc_data_structures" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } +rustc_macros = { path = "../rustc_macros" } +rustc_data_structures = { path = "../rustc_data_structures" } unicode-width = "0.1.4" atty = "0.2" termcolor = "1.0" diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 265ba59cccb..265ba59cccb 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs diff --git a/src/librustc_errors/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 870f7b81e21..870f7b81e21 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs diff --git a/src/librustc_errors/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index d1ff6f721c4..d1ff6f721c4 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs diff --git a/src/librustc_errors/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 5a654e83aed..5a654e83aed 100644 --- a/src/librustc_errors/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs diff --git a/src/librustc_errors/json.rs b/compiler/rustc_errors/src/json.rs index 750d36d3d89..750d36d3d89 100644 --- a/src/librustc_errors/json.rs +++ b/compiler/rustc_errors/src/json.rs diff --git a/src/librustc_errors/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index e69e868c8ed..e69e868c8ed 100644 --- a/src/librustc_errors/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs diff --git a/src/librustc_errors/lib.rs b/compiler/rustc_errors/src/lib.rs index d4f0a9d83ef..d4f0a9d83ef 100644 --- a/src/librustc_errors/lib.rs +++ b/compiler/rustc_errors/src/lib.rs diff --git a/src/librustc_errors/lock.rs b/compiler/rustc_errors/src/lock.rs index a73472021d4..a73472021d4 100644 --- a/src/librustc_errors/lock.rs +++ b/compiler/rustc_errors/src/lock.rs diff --git a/src/librustc_errors/registry.rs b/compiler/rustc_errors/src/registry.rs index b1d770d5bd5..b1d770d5bd5 100644 --- a/src/librustc_errors/registry.rs +++ b/compiler/rustc_errors/src/registry.rs diff --git a/src/librustc_errors/snippet.rs b/compiler/rustc_errors/src/snippet.rs index 160bf577799..160bf577799 100644 --- a/src/librustc_errors/snippet.rs +++ b/compiler/rustc_errors/src/snippet.rs diff --git a/src/librustc_errors/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index f2d255d7d95..f2d255d7d95 100644 --- a/src/librustc_errors/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml new file mode 100644 index 00000000000..25c2851f6de --- /dev/null +++ b/compiler/rustc_expand/Cargo.toml @@ -0,0 +1,26 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_expand" +version = "0.0.0" +edition = "2018" +build = false + +[lib] +doctest = false + +[dependencies] +rustc_serialize = { path = "../rustc_serialize" } +tracing = "0.1" +rustc_span = { path = "../rustc_span" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_ast_passes = { path = "../rustc_ast_passes" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_macros = { path = "../rustc_macros" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_parse = { path = "../rustc_parse" } +rustc_session = { path = "../rustc_session" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_ast = { path = "../rustc_ast" } diff --git a/src/librustc_expand/base.rs b/compiler/rustc_expand/src/base.rs index 4c01cb8159a..4c01cb8159a 100644 --- a/src/librustc_expand/base.rs +++ b/compiler/rustc_expand/src/base.rs diff --git a/src/librustc_expand/build.rs b/compiler/rustc_expand/src/build.rs index 9490b62aa17..9490b62aa17 100644 --- a/src/librustc_expand/build.rs +++ b/compiler/rustc_expand/src/build.rs diff --git a/src/librustc_expand/config.rs b/compiler/rustc_expand/src/config.rs index afd1e606402..97608a38903 100644 --- a/src/librustc_expand/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -403,10 +403,6 @@ impl<'a> StripUnconfigured<'a> { items.flat_map_in_place(|item| self.configure(item)); } - pub fn configure_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) { - params.flat_map_in_place(|param| self.configure(param)); - } - fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) { match vdata { ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) => { @@ -496,6 +492,13 @@ impl<'a> MutVisitor for StripUnconfigured<'a> { Some(expr) } + fn flat_map_generic_param( + &mut self, + param: ast::GenericParam, + ) -> SmallVec<[ast::GenericParam; 1]> { + noop_flat_map_generic_param(configure!(self, param), self) + } + fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { noop_flat_map_stmt(configure!(self, stmt), self) } diff --git a/src/librustc_expand/expand.rs b/compiler/rustc_expand/src/expand.rs index 7a21caf255a..105f81c6e0f 100644 --- a/src/librustc_expand/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -13,7 +13,7 @@ use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::{self as ast, AttrItem, Block, LitKind, NodeId, PatKind, Path}; -use rustc_ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind}; +use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; use rustc_data_structures::map_in_place::MapInPlace; @@ -1363,7 +1363,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } if let StmtKind::MacCall(mac) = stmt.kind { - let (mac, style, attrs) = mac.into_inner(); + let MacCallStmt { mac, style, attrs } = mac.into_inner(); self.check_attributes(&attrs); let mut placeholder = self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts(); @@ -1788,6 +1788,7 @@ pub struct ExpansionConfig<'feat> { pub should_test: bool, // If false, strip `#[test]` nodes pub keep_macs: bool, pub span_debug: bool, // If true, use verbose debugging for `proc_macro::Span` + pub proc_macro_backtrace: bool, // If true, show backtraces for proc-macro panics } impl<'feat> ExpansionConfig<'feat> { @@ -1800,6 +1801,7 @@ impl<'feat> ExpansionConfig<'feat> { should_test: false, keep_macs: false, span_debug: false, + proc_macro_backtrace: false, } } diff --git a/src/librustc_expand/lib.rs b/compiler/rustc_expand/src/lib.rs index 7f631cb71af..5436b1ef737 100644 --- a/src/librustc_expand/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -39,11 +39,6 @@ mod tests; mod parse { #[cfg(test)] mod tests; - #[cfg(test)] - mod lexer { - #[cfg(test)] - mod tests; - } } #[cfg(test)] mod tokenstream { diff --git a/src/librustc_expand/mbe.rs b/compiler/rustc_expand/src/mbe.rs index 9aed307ec93..9aed307ec93 100644 --- a/src/librustc_expand/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs diff --git a/src/librustc_expand/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index 6b419dae3f6..6b419dae3f6 100644 --- a/src/librustc_expand/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs diff --git a/src/librustc_expand/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 92a8f231126..92a8f231126 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs diff --git a/src/librustc_expand/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index f0e6fe39a3c..f0e6fe39a3c 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs diff --git a/src/librustc_expand/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 48db532c78f..48db532c78f 100644 --- a/src/librustc_expand/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs diff --git a/src/librustc_expand/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index b908a12c1fc..b908a12c1fc 100644 --- a/src/librustc_expand/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs diff --git a/src/librustc_expand/module.rs b/compiler/rustc_expand/src/module.rs index 1e123a2e145..1e123a2e145 100644 --- a/src/librustc_expand/module.rs +++ b/compiler/rustc_expand/src/module.rs diff --git a/src/librustc_expand/mut_visit/tests.rs b/compiler/rustc_expand/src/mut_visit/tests.rs index 38ff594b6e9..38ff594b6e9 100644 --- a/src/librustc_expand/mut_visit/tests.rs +++ b/compiler/rustc_expand/src/mut_visit/tests.rs diff --git a/src/librustc_expand/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 643305f153c..643305f153c 100644 --- a/src/librustc_expand/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs diff --git a/src/librustc_expand/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 29fb4c95ec6..dbd2e70af6a 100644 --- a/src/librustc_expand/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -92,7 +92,11 @@ pub fn placeholder( AstFragment::Ty(P(ast::Ty { id, span, kind: ast::TyKind::MacCall(mac_placeholder()) })) } AstFragmentKind::Stmts => AstFragment::Stmts(smallvec![{ - let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ast::AttrVec::new())); + let mac = P(ast::MacCallStmt { + mac: mac_placeholder(), + style: ast::MacStmtStyle::Braces, + attrs: ast::AttrVec::new(), + }); ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac) } }]), AstFragmentKind::Arms => AstFragment::Arms(smallvec![ast::Arm { @@ -293,7 +297,7 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { let (style, mut stmts) = match stmt.kind { - ast::StmtKind::MacCall(mac) => (mac.1, self.remove(stmt.id).make_stmts()), + ast::StmtKind::MacCall(mac) => (mac.style, self.remove(stmt.id).make_stmts()), _ => return noop_flat_map_stmt(stmt, self), }; diff --git a/src/librustc_expand/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 4e865c20d6f..94b3fcf2850 100644 --- a/src/librustc_expand/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -24,7 +24,7 @@ impl base::ProcMacro for BangProcMacro { input: TokenStream, ) -> Result<TokenStream, ErrorReported> { let server = proc_macro_server::Rustc::new(ecx); - self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| { + self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace).map_err(|e| { let mut err = ecx.struct_span_err(span, "proc macro panicked"); if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); @@ -48,14 +48,16 @@ impl base::AttrProcMacro for AttrProcMacro { annotated: TokenStream, ) -> Result<TokenStream, ErrorReported> { let server = proc_macro_server::Rustc::new(ecx); - self.client.run(&EXEC_STRATEGY, server, annotation, annotated).map_err(|e| { - let mut err = ecx.struct_span_err(span, "custom attribute panicked"); - if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); - } - err.emit(); - ErrorReported - }) + self.client + .run(&EXEC_STRATEGY, server, annotation, annotated, ecx.ecfg.proc_macro_backtrace) + .map_err(|e| { + let mut err = ecx.struct_span_err(span, "custom attribute panicked"); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); + } + err.emit(); + ErrorReported + }) } } @@ -111,17 +113,18 @@ impl MultiItemModifier for ProcMacroDerive { }; let server = proc_macro_server::Rustc::new(ecx); - let stream = match self.client.run(&EXEC_STRATEGY, server, input) { - Ok(stream) => stream, - Err(e) => { - let mut err = ecx.struct_span_err(span, "proc-macro derive panicked"); - if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); + let stream = + match self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace) { + Ok(stream) => stream, + Err(e) => { + let mut err = ecx.struct_span_err(span, "proc-macro derive panicked"); + if let Some(s) = e.as_str() { + err.help(&format!("message: {}", s)); + } + err.emit(); + return ExpandResult::Ready(vec![]); } - err.emit(); - return ExpandResult::Ready(vec![]); - } - }; + }; let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count(); let mut parser = diff --git a/src/librustc_expand/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 409784812f5..39c82f97e0a 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -189,7 +189,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)> } OpenDelim(..) | CloseDelim(..) => unreachable!(), - Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => unreachable!(), + Eof => unreachable!(), } } } diff --git a/src/librustc_expand/tests.rs b/compiler/rustc_expand/src/tests.rs index 6993ce58fa6..6993ce58fa6 100644 --- a/src/librustc_expand/tests.rs +++ b/compiler/rustc_expand/src/tests.rs diff --git a/src/librustc_expand/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs index 4e818e9feb0..4e818e9feb0 100644 --- a/src/librustc_expand/tokenstream/tests.rs +++ b/compiler/rustc_expand/src/tokenstream/tests.rs diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml new file mode 100644 index 00000000000..7a06bce13c8 --- /dev/null +++ b/compiler/rustc_feature/Cargo.toml @@ -0,0 +1,12 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_feature" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_span = { path = "../rustc_span" } diff --git a/src/librustc_feature/accepted.rs b/compiler/rustc_feature/src/accepted.rs index d16f023c00a..d16f023c00a 100644 --- a/src/librustc_feature/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs diff --git a/src/librustc_feature/active.rs b/compiler/rustc_feature/src/active.rs index e858980738d..e858980738d 100644 --- a/src/librustc_feature/active.rs +++ b/compiler/rustc_feature/src/active.rs diff --git a/src/librustc_feature/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 879f06f89a7..fc122db8ac1 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -5,10 +5,11 @@ use AttributeType::*; use crate::{Features, Stability}; -use lazy_static::lazy_static; use rustc_data_structures::fx::FxHashMap; use rustc_span::symbol::{sym, Symbol}; +use std::lazy::SyncLazy; + type GateFn = fn(&Features) -> bool; macro_rules! cfg_fn { @@ -589,8 +590,8 @@ pub fn is_builtin_attr_name(name: Symbol) -> bool { BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() } -lazy_static! { - pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = { +pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy<FxHashMap<Symbol, &'static BuiltinAttribute>> = + SyncLazy::new(|| { let mut map = FxHashMap::default(); for attr in BUILTIN_ATTRIBUTES.iter() { if map.insert(attr.0, attr).is_some() { @@ -598,5 +599,4 @@ lazy_static! { } } map - }; -} + }); diff --git a/src/librustc_feature/lib.rs b/compiler/rustc_feature/src/lib.rs index f8bf0315d0c..4393368cd45 100644 --- a/src/librustc_feature/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,6 +11,8 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. +#![feature(once_cell)] + mod accepted; mod active; mod builtin_attrs; diff --git a/src/librustc_feature/removed.rs b/compiler/rustc_feature/src/removed.rs index 8d410894e8b..8d410894e8b 100644 --- a/src/librustc_feature/removed.rs +++ b/compiler/rustc_feature/src/removed.rs diff --git a/src/librustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml index e74e3809927..e4414c788a7 100644 --- a/src/librustc_fs_util/Cargo.toml +++ b/compiler/rustc_fs_util/Cargo.toml @@ -3,9 +3,3 @@ authors = ["The Rust Project Developers"] name = "rustc_fs_util" version = "0.0.0" edition = "2018" - -[lib] -name = "rustc_fs_util" -path = "lib.rs" - -[dependencies] diff --git a/src/librustc_fs_util/lib.rs b/compiler/rustc_fs_util/src/lib.rs index 289b9f30c3b..289b9f30c3b 100644 --- a/src/librustc_fs_util/lib.rs +++ b/compiler/rustc_fs_util/src/lib.rs diff --git a/src/librustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml index 9a5e78a560c..d07b75a5c8f 100644 --- a/src/librustc_graphviz/Cargo.toml +++ b/compiler/rustc_graphviz/Cargo.toml @@ -3,7 +3,3 @@ authors = ["The Rust Project Developers"] name = "rustc_graphviz" version = "0.0.0" edition = "2018" - -[lib] -name = "rustc_graphviz" -path = "lib.rs" diff --git a/src/librustc_graphviz/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 4339092b63e..4339092b63e 100644 --- a/src/librustc_graphviz/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs diff --git a/src/librustc_graphviz/tests.rs b/compiler/rustc_graphviz/src/tests.rs index 055e13156ae..055e13156ae 100644 --- a/src/librustc_graphviz/tests.rs +++ b/compiler/rustc_graphviz/src/tests.rs diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml new file mode 100644 index 00000000000..b24c208c76a --- /dev/null +++ b/compiler/rustc_hir/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_hir" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_target = { path = "../rustc_target" } +rustc_macros = { path = "../rustc_macros" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } +rustc_span = { path = "../rustc_span" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_ast = { path = "../rustc_ast" } +tracing = "0.1" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_hir/arena.rs b/compiler/rustc_hir/src/arena.rs index 85ab7906d25..85ab7906d25 100644 --- a/src/librustc_hir/arena.rs +++ b/compiler/rustc_hir/src/arena.rs diff --git a/src/librustc_hir/def.rs b/compiler/rustc_hir/src/def.rs index 0d61dc037c6..0d61dc037c6 100644 --- a/src/librustc_hir/def.rs +++ b/compiler/rustc_hir/src/def.rs diff --git a/src/librustc_hir/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 45735ead256..45735ead256 100644 --- a/src/librustc_hir/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs diff --git a/src/librustc_hir/hir.rs b/compiler/rustc_hir/src/hir.rs index cd4185226dc..cd4185226dc 100644 --- a/src/librustc_hir/hir.rs +++ b/compiler/rustc_hir/src/hir.rs diff --git a/src/librustc_hir/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index fea850c12d9..fea850c12d9 100644 --- a/src/librustc_hir/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs diff --git a/src/librustc_hir/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 76cf6bd4776..76cf6bd4776 100644 --- a/src/librustc_hir/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs diff --git a/src/librustc_hir/itemlikevisit.rs b/compiler/rustc_hir/src/itemlikevisit.rs index 369cd49621b..369cd49621b 100644 --- a/src/librustc_hir/itemlikevisit.rs +++ b/compiler/rustc_hir/src/itemlikevisit.rs diff --git a/src/librustc_hir/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index acf6847c014..5e4c03bec83 100644 --- a/src/librustc_hir/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -17,7 +17,7 @@ use rustc_macros::HashStable_Generic; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use lazy_static::lazy_static; +use std::lazy::SyncLazy; pub enum LangItemGroup { Op, @@ -117,14 +117,12 @@ macro_rules! language_item_table { )* } - lazy_static! { - /// A mapping from the name of the lang item to its order and the form it must be of. - pub static ref ITEM_REFS: FxHashMap<Symbol, (usize, Target)> = { - let mut item_refs = FxHashMap::default(); - $( item_refs.insert($name, (LangItem::$variant as usize, $target)); )* - item_refs - }; - } + /// A mapping from the name of the lang item to its order and the form it must be of. + pub static ITEM_REFS: SyncLazy<FxHashMap<Symbol, (usize, Target)>> = SyncLazy::new(|| { + let mut item_refs = FxHashMap::default(); + $( item_refs.insert($name, (LangItem::$variant as usize, $target)); )* + item_refs + }); // End of the macro } diff --git a/src/librustc_hir/lib.rs b/compiler/rustc_hir/src/lib.rs index 19ea1de5683..c69a9b063ae 100644 --- a/src/librustc_hir/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -6,6 +6,7 @@ #![feature(const_fn)] // For the unsizing cast on `&[]` #![feature(const_panic)] #![feature(in_band_lifetimes)] +#![feature(once_cell)] #![feature(or_patterns)] #![recursion_limit = "256"] diff --git a/src/librustc_hir/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index 2f1b5da8e13..2f1b5da8e13 100644 --- a/src/librustc_hir/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs diff --git a/src/librustc_hir/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 1d3f44a0899..1d3f44a0899 100644 --- a/src/librustc_hir/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs diff --git a/src/librustc_hir/target.rs b/compiler/rustc_hir/src/target.rs index 1efc8bc3124..1efc8bc3124 100644 --- a/src/librustc_hir/target.rs +++ b/compiler/rustc_hir/src/target.rs diff --git a/src/librustc_hir/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs index 129eec7d29e..52f28bf8f4c 100644 --- a/src/librustc_hir/weak_lang_items.rs +++ b/compiler/rustc_hir/src/weak_lang_items.rs @@ -7,18 +7,16 @@ use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_span::symbol::{sym, Symbol}; -use lazy_static::lazy_static; +use std::lazy::SyncLazy; macro_rules! weak_lang_items { ($($name:ident, $item:ident, $sym:ident;)*) => ( -lazy_static! { - pub static ref WEAK_ITEMS_REFS: FxHashMap<Symbol, LangItem> = { - let mut map = FxHashMap::default(); - $(map.insert(sym::$name, LangItem::$item);)* - map - }; -} +pub static WEAK_ITEMS_REFS: SyncLazy<FxHashMap<Symbol, LangItem>> = SyncLazy::new(|| { + let mut map = FxHashMap::default(); + $(map.insert(sym::$name, LangItem::$item);)* + map +}); /// The `check_name` argument avoids the need for `librustc_hir` to depend on /// `librustc_session`. diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml new file mode 100644 index 00000000000..1f7643e9fb4 --- /dev/null +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -0,0 +1,15 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_hir_pretty" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_hir = { path = "../rustc_hir" } +rustc_target = { path = "../rustc_target" } +rustc_span = { path = "../rustc_span" } +rustc_ast = { path = "../rustc_ast" } diff --git a/src/librustc_hir_pretty/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index f6e4b1fb418..f6e4b1fb418 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml new file mode 100644 index 00000000000..049e5b8b722 --- /dev/null +++ b/compiler/rustc_incremental/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_incremental" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_graphviz = { path = "../rustc_graphviz" } +tracing = "0.1" +rand = "0.7" +rustc_middle = { path = "../rustc_middle" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hir = { path = "../rustc_hir" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_ast = { path = "../rustc_ast" } +rustc_macros = { path = "../rustc_macros" } +rustc_span = { path = "../rustc_span" } +rustc_fs_util = { path = "../rustc_fs_util" } +rustc_session = { path = "../rustc_session" } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index e17396422f1..e17396422f1 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs diff --git a/src/librustc_incremental/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs index 80448c01a26..80448c01a26 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/compiler/rustc_incremental/src/assert_module_sources.rs diff --git a/src/librustc_incremental/lib.rs b/compiler/rustc_incremental/src/lib.rs index ad189138054..ad189138054 100644 --- a/src/librustc_incremental/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs diff --git a/src/librustc_incremental/persist/README.md b/compiler/rustc_incremental/src/persist/README.md index b01fe219e1e..b01fe219e1e 100644 --- a/src/librustc_incremental/persist/README.md +++ b/compiler/rustc_incremental/src/persist/README.md diff --git a/src/librustc_incremental/persist/data.rs b/compiler/rustc_incremental/src/persist/data.rs index 81e5410978d..81e5410978d 100644 --- a/src/librustc_incremental/persist/data.rs +++ b/compiler/rustc_incremental/src/persist/data.rs diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index f0a10885550..f0a10885550 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs diff --git a/src/librustc_incremental/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index 048a81b81ba..048a81b81ba 100644 --- a/src/librustc_incremental/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs diff --git a/src/librustc_incremental/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 4926f726f35..4926f726f35 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs diff --git a/src/librustc_incremental/persist/fs/tests.rs b/compiler/rustc_incremental/src/persist/fs/tests.rs index 652ef6bcdce..652ef6bcdce 100644 --- a/src/librustc_incremental/persist/fs/tests.rs +++ b/compiler/rustc_incremental/src/persist/fs/tests.rs diff --git a/src/librustc_incremental/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 966faa9639d..966faa9639d 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs diff --git a/src/librustc_incremental/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index 7bc3b47e15a..7bc3b47e15a 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs diff --git a/src/librustc_incremental/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index c43d4ad4049..c43d4ad4049 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs diff --git a/src/librustc_incremental/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 19d64bda56d..19d64bda56d 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs diff --git a/src/librustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index 8aaf1cb9cbc..6ac7c06ee83 100644 --- a/src/librustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -5,11 +5,9 @@ version = "0.0.0" edition = "2018" [lib] -name = "rustc_index" -path = "lib.rs" doctest = false [dependencies] arrayvec = "0.5.1" -rustc_serialize = { path = "../librustc_serialize" } -rustc_macros = { path = "../librustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_macros = { path = "../rustc_macros" } diff --git a/src/librustc_index/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index c43d1a6830d..c43d1a6830d 100644 --- a/src/librustc_index/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs diff --git a/src/librustc_index/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 6cc3e9427d1..6cc3e9427d1 100644 --- a/src/librustc_index/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs diff --git a/src/librustc_index/lib.rs b/compiler/rustc_index/src/lib.rs index 7ee881b0639..7ee881b0639 100644 --- a/src/librustc_index/lib.rs +++ b/compiler/rustc_index/src/lib.rs diff --git a/src/librustc_index/vec.rs b/compiler/rustc_index/src/vec.rs index 2420f82c041..2420f82c041 100644 --- a/src/librustc_index/vec.rs +++ b/compiler/rustc_index/src/vec.rs diff --git a/src/librustc_index/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs index 15c43c72c7b..15c43c72c7b 100644 --- a/src/librustc_index/vec/tests.rs +++ b/compiler/rustc_index/src/vec/tests.rs diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml new file mode 100644 index 00000000000..5dba4106c94 --- /dev/null +++ b/compiler/rustc_infer/Cargo.toml @@ -0,0 +1,24 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_infer" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_graphviz = { path = "../rustc_graphviz" } +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } +rustc_session = { path = "../rustc_session" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_ast = { path = "../rustc_ast" } diff --git a/src/librustc_infer/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index a7749d33b7c..a7749d33b7c 100644 --- a/src/librustc_infer/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index ea32a1ae5a5..ea32a1ae5a5 100644 --- a/src/librustc_infer/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs diff --git a/src/librustc_infer/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 2b8c46f1de4..2b8c46f1de4 100644 --- a/src/librustc_infer/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 0dbebac7e36..0dbebac7e36 100644 --- a/src/librustc_infer/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs diff --git a/src/librustc_infer/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index 65791f6fc65..65791f6fc65 100644 --- a/src/librustc_infer/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs diff --git a/src/librustc_infer/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 3a54a647530..3a54a647530 100644 --- a/src/librustc_infer/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs diff --git a/src/librustc_infer/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 7de752d1de0..7de752d1de0 100644 --- a/src/librustc_infer/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index d72ed72e3a8..d72ed72e3a8 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs diff --git a/src/librustc_infer/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index bf087dfacfa..bf087dfacfa 100644 --- a/src/librustc_infer/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 7ab18e54f7e..7ab18e54f7e 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index eb1521f0565..eb1521f0565 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index cc8f1816bc3..cc8f1816bc3 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 89142edb2dc..89142edb2dc 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 2187064ec5e..2187064ec5e 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 7493b8b0a9f..7493b8b0a9f 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 788eabf296d..788eabf296d 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 6e2d49f1ad7..6e2d49f1ad7 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs diff --git a/src/librustc_infer/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 9ac27030ade..9ac27030ade 100644 --- a/src/librustc_infer/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs diff --git a/src/librustc_infer/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index ffe5fb172be..ffe5fb172be 100644 --- a/src/librustc_infer/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs diff --git a/src/librustc_infer/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 02bebe10ed0..02bebe10ed0 100644 --- a/src/librustc_infer/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs diff --git a/src/librustc_infer/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index c6651108df5..c6651108df5 100644 --- a/src/librustc_infer/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs diff --git a/src/librustc_infer/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index ccba904df9e..ccba904df9e 100644 --- a/src/librustc_infer/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs diff --git a/src/librustc_infer/infer/higher_ranked/README.md b/compiler/rustc_infer/src/infer/higher_ranked/README.md index 533d0ef7e6c..533d0ef7e6c 100644 --- a/src/librustc_infer/infer/higher_ranked/README.md +++ b/compiler/rustc_infer/src/infer/higher_ranked/README.md diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index ea19dff7db1..ea19dff7db1 100644 --- a/src/librustc_infer/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs diff --git a/src/librustc_infer/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs index 1bf43e74dcd..1bf43e74dcd 100644 --- a/src/librustc_infer/infer/lattice.rs +++ b/compiler/rustc_infer/src/infer/lattice.rs diff --git a/src/librustc_infer/infer/lexical_region_resolve/README.md b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md index e0b2c0bffee..e0b2c0bffee 100644 --- a/src/librustc_infer/infer/lexical_region_resolve/README.md +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index fcf1949933b..fcf1949933b 100644 --- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs diff --git a/src/librustc_infer/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index 3e2ea3d0f8f..3e2ea3d0f8f 100644 --- a/src/librustc_infer/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs diff --git a/src/librustc_infer/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 3744ad5d032..3744ad5d032 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs diff --git a/src/librustc_infer/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 3f5ed36035c..3f5ed36035c 100644 --- a/src/librustc_infer/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs diff --git a/src/librustc_infer/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 1a9e20e79fe..1a9e20e79fe 100644 --- a/src/librustc_infer/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs diff --git a/src/librustc_infer/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index a1e7f1fa3e5..a1e7f1fa3e5 100644 --- a/src/librustc_infer/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs diff --git a/src/librustc_infer/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 48f6d937f2f..48f6d937f2f 100644 --- a/src/librustc_infer/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs diff --git a/src/librustc_infer/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 8f20b5743df..8f20b5743df 100644 --- a/src/librustc_infer/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs diff --git a/src/librustc_infer/infer/region_constraints/README.md b/compiler/rustc_infer/src/infer/region_constraints/README.md index 0231dd06677..0231dd06677 100644 --- a/src/librustc_infer/infer/region_constraints/README.md +++ b/compiler/rustc_infer/src/infer/region_constraints/README.md diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 2d4c1e5d050..2d4c1e5d050 100644 --- a/src/librustc_infer/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 2902c41a6bc..2902c41a6bc 100644 --- a/src/librustc_infer/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs diff --git a/src/librustc_infer/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 74f365ced23..74f365ced23 100644 --- a/src/librustc_infer/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs diff --git a/src/librustc_infer/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 308f884f9a6..308f884f9a6 100644 --- a/src/librustc_infer/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs diff --git a/src/librustc_infer/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 53c7dcc6377..53c7dcc6377 100644 --- a/src/librustc_infer/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs diff --git a/src/librustc_infer/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs index 2cfd6bb904c..2cfd6bb904c 100644 --- a/src/librustc_infer/infer/undo_log.rs +++ b/compiler/rustc_infer/src/infer/undo_log.rs diff --git a/src/librustc_infer/lib.rs b/compiler/rustc_infer/src/lib.rs index e05041d8846..e05041d8846 100644 --- a/src/librustc_infer/lib.rs +++ b/compiler/rustc_infer/src/lib.rs diff --git a/src/librustc_infer/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 2710debea94..2710debea94 100644 --- a/src/librustc_infer/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index f873358ff9f..f873358ff9f 100644 --- a/src/librustc_infer/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs diff --git a/src/librustc_infer/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 7e7c8588ffb..7e7c8588ffb 100644 --- a/src/librustc_infer/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs diff --git a/src/librustc_infer/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 65284bcee91..65284bcee91 100644 --- a/src/librustc_infer/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs diff --git a/src/librustc_infer/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index c48e58c0482..c48e58c0482 100644 --- a/src/librustc_infer/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs diff --git a/src/librustc_infer/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 93fc7f1f3b8..93fc7f1f3b8 100644 --- a/src/librustc_infer/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml new file mode 100644 index 00000000000..e214493a567 --- /dev/null +++ b/compiler/rustc_interface/Cargo.toml @@ -0,0 +1,54 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_interface" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +libc = "0.2" +tracing = "0.1" +rayon = { version = "0.3.0", package = "rustc-rayon" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_ast = { path = "../rustc_ast" } +rustc_attr = { path = "../rustc_attr" } +rustc_builtin_macros = { path = "../rustc_builtin_macros" } +rustc_expand = { path = "../rustc_expand" } +rustc_parse = { path = "../rustc_parse" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_middle = { path = "../rustc_middle" } +rustc_ast_lowering = { path = "../rustc_ast_lowering" } +rustc_ast_passes = { path = "../rustc_ast_passes" } +rustc_incremental = { path = "../rustc_incremental" } +rustc_traits = { path = "../rustc_traits" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } +rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true } +rustc_hir = { path = "../rustc_hir" } +rustc_metadata = { path = "../rustc_metadata" } +rustc_mir = { path = "../rustc_mir" } +rustc_mir_build = { path = "../rustc_mir_build" } +rustc_passes = { path = "../rustc_passes" } +rustc_typeck = { path = "../rustc_typeck" } +rustc_lint = { path = "../rustc_lint" } +rustc_errors = { path = "../rustc_errors" } +rustc_plugin_impl = { path = "../rustc_plugin_impl" } +rustc_privacy = { path = "../rustc_privacy" } +rustc_resolve = { path = "../rustc_resolve" } +rustc_trait_selection = { path = "../rustc_trait_selection" } +rustc_ty = { path = "../rustc_ty" } +tempfile = "3.0.5" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi"] } + +[dev-dependencies] +rustc_target = { path = "../rustc_target" } + +[features] +llvm = ['rustc_codegen_llvm'] diff --git a/src/librustc_interface/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 7fa1a3eb0f5..7fa1a3eb0f5 100644 --- a/src/librustc_interface/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs diff --git a/src/librustc_interface/interface.rs b/compiler/rustc_interface/src/interface.rs index 4d84462c42b..4d84462c42b 100644 --- a/src/librustc_interface/interface.rs +++ b/compiler/rustc_interface/src/interface.rs diff --git a/src/librustc_interface/lib.rs b/compiler/rustc_interface/src/lib.rs index fe40c615f79..88d2efe96d1 100644 --- a/src/librustc_interface/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -4,6 +4,7 @@ #![feature(nll)] #![feature(generator_trait)] #![feature(generators)] +#![feature(once_cell)] #![recursion_limit = "256"] mod callbacks; diff --git a/src/librustc_interface/passes.rs b/compiler/rustc_interface/src/passes.rs index 403aea8b304..66d3765d347 100644 --- a/src/librustc_interface/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -2,7 +2,6 @@ use crate::interface::{Compiler, Result}; use crate::proc_macro_decls; use crate::util; -use once_cell::sync::Lazy; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::{self as ast, visit}; use rustc_codegen_ssa::back::link::emit_metadata; @@ -46,6 +45,7 @@ use std::any::Any; use std::cell::RefCell; use std::ffi::OsString; use std::io::{self, BufWriter, Write}; +use std::lazy::SyncLazy; use std::path::PathBuf; use std::rc::Rc; use std::{env, fs, iter, mem}; @@ -291,6 +291,7 @@ fn configure_and_expand_inner<'a>( trace_mac: sess.opts.debugging_opts.trace_macros, should_test: sess.opts.test, span_debug: sess.opts.debugging_opts.span_debug, + proc_macro_backtrace: sess.opts.debugging_opts.proc_macro_backtrace, ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string()) }; @@ -680,7 +681,7 @@ pub fn prepare_outputs( Ok(outputs) } -pub static DEFAULT_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| { +pub static DEFAULT_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| { let providers = &mut Providers::default(); providers.analysis = analysis; proc_macro_decls::provide(providers); @@ -703,7 +704,7 @@ pub static DEFAULT_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| { *providers }); -pub static DEFAULT_EXTERN_QUERY_PROVIDERS: Lazy<Providers> = Lazy::new(|| { +pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|| { let mut extern_providers = *DEFAULT_QUERY_PROVIDERS; rustc_metadata::provide_extern(&mut extern_providers); rustc_codegen_ssa::provide_extern(&mut extern_providers); diff --git a/src/librustc_interface/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index d56115fd6ac..d56115fd6ac 100644 --- a/src/librustc_interface/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs diff --git a/src/librustc_interface/queries.rs b/compiler/rustc_interface/src/queries.rs index 8b82217a91a..8b82217a91a 100644 --- a/src/librustc_interface/queries.rs +++ b/compiler/rustc_interface/src/queries.rs diff --git a/src/librustc_interface/tests.rs b/compiler/rustc_interface/src/tests.rs index e94745519a4..ada8dc90494 100644 --- a/src/librustc_interface/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -402,6 +402,7 @@ fn test_codegen_options_tracking_hash() { // `link_arg` is omitted because it just forwards to `link_args`. untracked!(link_args, vec![String::from("abc"), String::from("def")]); untracked!(link_dead_code, Some(true)); + untracked!(link_self_contained, Some(true)); untracked!(linker, Some(PathBuf::from("linker"))); untracked!(linker_flavor, Some(LinkerFlavor::Gcc)); untracked!(no_stack_check, true); @@ -502,6 +503,7 @@ fn test_debugging_options_tracking_hash() { untracked!(print_llvm_passes, true); untracked!(print_mono_items, Some(String::from("abc"))); untracked!(print_type_sizes, true); + untracked!(proc_macro_backtrace, true); untracked!(query_dep_graph, true); untracked!(query_stats, true); untracked!(save_analysis, true); diff --git a/src/librustc_interface/util.rs b/compiler/rustc_interface/src/util.rs index 8816ba198cf..b1b39fd1ad2 100644 --- a/src/librustc_interface/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -25,6 +25,7 @@ use rustc_span::symbol::{sym, Symbol}; use smallvec::SmallVec; use std::env; use std::io::{self, Write}; +use std::lazy::SyncOnceCell; use std::mem; use std::ops::DerefMut; use std::path::{Path, PathBuf}; @@ -243,8 +244,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> { // loading, so we leave the code here. It is potentially useful for other tools // that want to invoke the rustc binary while linking to rustc as well. pub fn rustc_path<'a>() -> Option<&'a Path> { - static RUSTC_PATH: once_cell::sync::OnceCell<Option<PathBuf>> = - once_cell::sync::OnceCell::new(); + static RUSTC_PATH: SyncOnceCell<Option<PathBuf>> = SyncOnceCell::new(); const BIN_PATH: &str = env!("RUSTC_INSTALL_BINDIR"); diff --git a/src/librustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index 28b56f6fef4..12101776de2 100644 --- a/src/librustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -14,11 +14,10 @@ Rust lexer used by rustc. No stability guarantees are provided. # This will be used when publishing this crate as `rustc-ap-rustc_lexer`. [lib] doctest = false -name = "rustc_lexer" # Note that this crate purposefully does not depend on other rustc crates [dependencies] unicode-xid = "0.2.0" [dev-dependencies] -expect-test = "0.1" +expect-test = "1.0" diff --git a/src/librustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs index c0045d3f79b..c0045d3f79b 100644 --- a/src/librustc_lexer/src/cursor.rs +++ b/compiler/rustc_lexer/src/cursor.rs diff --git a/src/librustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index b7d6194cd77..44999bbe857 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -191,12 +191,16 @@ pub fn strip_shebang(input: &str) -> Option<usize> { // For simplicity we consider any line starting with `#!` a shebang, // regardless of restrictions put on shebangs by specific platforms. if let Some(input_tail) = input.strip_prefix("#!") { - // Ok, this is a shebang but if the next non-whitespace token is `[` or maybe - // a doc comment (due to `TokenKind::(Line,Block)Comment` ambiguity at lexer level), + // Ok, this is a shebang but if the next non-whitespace token is `[`, // then it may be valid Rust code, so consider it Rust code. - let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| - !matches!(tok, TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }) - ); + let next_non_whitespace_token = tokenize(input_tail).map(|tok| tok.kind).find(|tok| { + !matches!( + tok, + TokenKind::Whitespace + | TokenKind::LineComment { doc_style: None } + | TokenKind::BlockComment { doc_style: None, .. } + ) + }); if next_non_whitespace_token != Some(TokenKind::OpenBracket) { // No other choice than to consider this a shebang. return Some(2 + input_tail.lines().next().unwrap_or_default().len()); diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs new file mode 100644 index 00000000000..94017b7b286 --- /dev/null +++ b/compiler/rustc_lexer/src/tests.rs @@ -0,0 +1,287 @@ +use super::*; + +use expect_test::{expect, Expect}; + +fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) { + let s = &format!("r{}", s); + let mut cursor = Cursor::new(s); + cursor.bump(); + let (n_hashes, err) = cursor.raw_double_quoted_string(0); + assert_eq!(n_hashes, expected_hashes); + assert_eq!(err, expected_err); +} + +#[test] +fn test_naked_raw_str() { + check_raw_str(r#""abc""#, 0, None); +} + +#[test] +fn test_raw_no_start() { + check_raw_str(r##""abc"#"##, 0, None); +} + +#[test] +fn test_too_many_terminators() { + // this error is handled in the parser later + check_raw_str(r###"#"abc"##"###, 1, None); +} + +#[test] +fn test_unterminated() { + check_raw_str( + r#"#"abc"#, + 1, + Some(RawStrError::NoTerminator { expected: 1, found: 0, possible_terminator_offset: None }), + ); + check_raw_str( + r###"##"abc"#"###, + 2, + Some(RawStrError::NoTerminator { + expected: 2, + found: 1, + possible_terminator_offset: Some(7), + }), + ); + // We're looking for "# not just any # + check_raw_str( + r###"##"abc#"###, + 2, + Some(RawStrError::NoTerminator { expected: 2, found: 0, possible_terminator_offset: None }), + ) +} + +#[test] +fn test_invalid_start() { + check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' })); +} + +#[test] +fn test_unterminated_no_pound() { + // https://github.com/rust-lang/rust/issues/70677 + check_raw_str( + r#"""#, + 0, + Some(RawStrError::NoTerminator { expected: 0, found: 0, possible_terminator_offset: None }), + ); +} + +#[test] +fn test_valid_shebang() { + // https://github.com/rust-lang/rust/issues/70528 + let input = "#!/usr/bin/rustrun\nlet x = 5;"; + assert_eq!(strip_shebang(input), Some(18)); +} + +#[test] +fn test_invalid_shebang_valid_rust_syntax() { + // https://github.com/rust-lang/rust/issues/70528 + let input = "#! [bad_attribute]"; + assert_eq!(strip_shebang(input), None); +} + +#[test] +fn test_shebang_second_line() { + // Because shebangs are interpreted by the kernel, they must be on the first line + let input = "\n#!/bin/bash"; + assert_eq!(strip_shebang(input), None); +} + +#[test] +fn test_shebang_space() { + let input = "#! /bin/bash"; + assert_eq!(strip_shebang(input), Some(input.len())); +} + +#[test] +fn test_shebang_empty_shebang() { + let input = "#! \n[attribute(foo)]"; + assert_eq!(strip_shebang(input), None); +} + +#[test] +fn test_invalid_shebang_comment() { + let input = "#!//bin/ami/a/comment\n["; + assert_eq!(strip_shebang(input), None) +} + +#[test] +fn test_invalid_shebang_another_comment() { + let input = "#!/*bin/ami/a/comment*/\n[attribute"; + assert_eq!(strip_shebang(input), None) +} + +#[test] +fn test_shebang_valid_rust_after() { + let input = "#!/*bin/ami/a/comment*/\npub fn main() {}"; + assert_eq!(strip_shebang(input), Some(23)) +} + +#[test] +fn test_shebang_followed_by_attrib() { + let input = "#!/bin/rust-scripts\n#![allow_unused(true)]"; + assert_eq!(strip_shebang(input), Some(19)); +} + +fn check_lexing(src: &str, expect: Expect) { + let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect(); + expect.assert_eq(&actual) +} + +#[test] +fn smoke_test() { + check_lexing( + "/* my source file */ fn main() { println!(\"zebra\"); }\n", + expect![[r#" + Token { kind: BlockComment { doc_style: None, terminated: true }, len: 20 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 2 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 4 } + Token { kind: OpenParen, len: 1 } + Token { kind: CloseParen, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: OpenBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: Ident, len: 7 } + Token { kind: Bang, len: 1 } + Token { kind: OpenParen, len: 1 } + Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 7 }, len: 7 } + Token { kind: CloseParen, len: 1 } + Token { kind: Semi, len: 1 } + Token { kind: Whitespace, len: 1 } + Token { kind: CloseBrace, len: 1 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} + +#[test] +fn comment_flavors() { + check_lexing( + r" +// line +//// line as well +/// outer doc line +//! inner doc line +/* block */ +/**/ +/*** also block */ +/** outer doc block */ +/*! inner doc block */ +", + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: LineComment { doc_style: None }, len: 7 } + Token { kind: Whitespace, len: 1 } + Token { kind: LineComment { doc_style: None }, len: 17 } + Token { kind: Whitespace, len: 1 } + Token { kind: LineComment { doc_style: Some(Outer) }, len: 18 } + Token { kind: Whitespace, len: 1 } + Token { kind: LineComment { doc_style: Some(Inner) }, len: 18 } + Token { kind: Whitespace, len: 1 } + Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 } + Token { kind: Whitespace, len: 1 } + Token { kind: BlockComment { doc_style: None, terminated: true }, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: BlockComment { doc_style: None, terminated: true }, len: 18 } + Token { kind: Whitespace, len: 1 } + Token { kind: BlockComment { doc_style: Some(Outer), terminated: true }, len: 22 } + Token { kind: Whitespace, len: 1 } + Token { kind: BlockComment { doc_style: Some(Inner), terminated: true }, len: 22 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} + +#[test] +fn nested_block_comments() { + check_lexing( + "/* /* */ */'a'", + expect![[r#" + Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 } + Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } + "#]], + ) +} + +#[test] +fn characters() { + check_lexing( + "'a' ' ' '\\n'", + expect![[r#" + Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 4 }, len: 4 } + "#]], + ); +} + +#[test] +fn lifetime() { + check_lexing( + "'abc", + expect![[r#" + Token { kind: Lifetime { starts_with_number: false }, len: 4 } + "#]], + ); +} + +#[test] +fn raw_string() { + check_lexing( + "r###\"\"#a\\b\x00c\"\"###", + expect![[r#" + Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 17 }, len: 17 } + "#]], + ) +} + +#[test] +fn literal_suffixes() { + check_lexing( + r####" +'a' +b'a' +"a" +b"a" +1234 +0b101 +0xABC +1.0 +1.0e10 +2us +r###"raw"###suffix +br###"raw"###suffix +"####, + expect![[r#" + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Char { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Byte { terminated: true }, suffix_start: 4 }, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Str { terminated: true }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: ByteStr { terminated: true }, suffix_start: 4 }, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 4 }, len: 4 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Int { base: Binary, empty_int: false }, suffix_start: 5 }, len: 5 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Int { base: Hexadecimal, empty_int: false }, suffix_start: 5 }, len: 5 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 3 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 6 }, len: 6 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 1 }, len: 3 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: RawStr { n_hashes: 3, err: None }, suffix_start: 12 }, len: 18 } + Token { kind: Whitespace, len: 1 } + Token { kind: Literal { kind: RawByteStr { n_hashes: 3, err: None }, suffix_start: 13 }, len: 19 } + Token { kind: Whitespace, len: 1 } + "#]], + ) +} diff --git a/src/librustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 697d25fdb58..697d25fdb58 100644 --- a/src/librustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs diff --git a/src/librustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs index f2b751a78f2..f2b751a78f2 100644 --- a/src/librustc_lexer/src/unescape/tests.rs +++ b/compiler/rustc_lexer/src/unescape/tests.rs diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml new file mode 100644 index 00000000000..760a8e385d6 --- /dev/null +++ b/compiler/rustc_lint/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_lint" +version = "0.0.0" +edition = "2018" + +[dependencies] +tracing = "0.1" +unicode-security = "0.0.5" +rustc_middle = { path = "../rustc_middle" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr = { path = "../rustc_attr" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_target = { path = "../rustc_target" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_feature = { path = "../rustc_feature" } +rustc_index = { path = "../rustc_index" } +rustc_session = { path = "../rustc_session" } +rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/src/librustc_lint/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index 9d74ad3b2f5..9d74ad3b2f5 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs diff --git a/src/librustc_lint/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ea624b9ed30..ea624b9ed30 100644 --- a/src/librustc_lint/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs diff --git a/src/librustc_lint/context.rs b/compiler/rustc_lint/src/context.rs index a6784ffffcd..a6784ffffcd 100644 --- a/src/librustc_lint/context.rs +++ b/compiler/rustc_lint/src/context.rs diff --git a/src/librustc_lint/early.rs b/compiler/rustc_lint/src/early.rs index 998676d44d2..998676d44d2 100644 --- a/src/librustc_lint/early.rs +++ b/compiler/rustc_lint/src/early.rs diff --git a/src/librustc_lint/internal.rs b/compiler/rustc_lint/src/internal.rs index 100e555f299..100e555f299 100644 --- a/src/librustc_lint/internal.rs +++ b/compiler/rustc_lint/src/internal.rs diff --git a/src/librustc_lint/late.rs b/compiler/rustc_lint/src/late.rs index a6c04fb0b4c..a6c04fb0b4c 100644 --- a/src/librustc_lint/late.rs +++ b/compiler/rustc_lint/src/late.rs diff --git a/src/librustc_lint/levels.rs b/compiler/rustc_lint/src/levels.rs index 48254dcee82..48254dcee82 100644 --- a/src/librustc_lint/levels.rs +++ b/compiler/rustc_lint/src/levels.rs diff --git a/src/librustc_lint/lib.rs b/compiler/rustc_lint/src/lib.rs index 0a14b16e274..0a14b16e274 100644 --- a/src/librustc_lint/lib.rs +++ b/compiler/rustc_lint/src/lib.rs diff --git a/src/librustc_lint/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 2f0b2a8d680..2f0b2a8d680 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs diff --git a/src/librustc_lint/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index f23e8c5e208..f23e8c5e208 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs diff --git a/src/librustc_lint/nonstandard_style/tests.rs b/compiler/rustc_lint/src/nonstandard_style/tests.rs index 39c525b8623..39c525b8623 100644 --- a/src/librustc_lint/nonstandard_style/tests.rs +++ b/compiler/rustc_lint/src/nonstandard_style/tests.rs diff --git a/src/librustc_lint/passes.rs b/compiler/rustc_lint/src/passes.rs index 159286c13a4..159286c13a4 100644 --- a/src/librustc_lint/passes.rs +++ b/compiler/rustc_lint/src/passes.rs diff --git a/src/librustc_lint/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index d4aa4968f25..d4aa4968f25 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs diff --git a/src/librustc_lint/types.rs b/compiler/rustc_lint/src/types.rs index 35c462c24c8..35c462c24c8 100644 --- a/src/librustc_lint/types.rs +++ b/compiler/rustc_lint/src/types.rs diff --git a/src/librustc_lint/unused.rs b/compiler/rustc_lint/src/unused.rs index c793e81ebe3..c793e81ebe3 100644 --- a/src/librustc_lint/unused.rs +++ b/compiler/rustc_lint/src/unused.rs diff --git a/src/librustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index 73eb0dd56d7..73eb0dd56d7 100644 --- a/src/librustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml diff --git a/src/librustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs index c955c137782..c955c137782 100644 --- a/src/librustc_macros/src/hash_stable.rs +++ b/compiler/rustc_macros/src/hash_stable.rs diff --git a/src/librustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 7fb3b0e7ea6..7fb3b0e7ea6 100644 --- a/src/librustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs diff --git a/src/librustc_macros/src/lift.rs b/compiler/rustc_macros/src/lift.rs index 4bf4ce00a4d..4bf4ce00a4d 100644 --- a/src/librustc_macros/src/lift.rs +++ b/compiler/rustc_macros/src/lift.rs diff --git a/src/librustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index c17d5311e8f..c17d5311e8f 100644 --- a/src/librustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs diff --git a/src/librustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index dbeb3c75504..dbeb3c75504 100644 --- a/src/librustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs diff --git a/src/librustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs index 352665f0ab1..352665f0ab1 100644 --- a/src/librustc_macros/src/symbols.rs +++ b/compiler/rustc_macros/src/symbols.rs diff --git a/src/librustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index 6931e6552ad..6931e6552ad 100644 --- a/src/librustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml new file mode 100644 index 00000000000..4b144f94ea7 --- /dev/null +++ b/compiler/rustc_metadata/Cargo.toml @@ -0,0 +1,33 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_metadata" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +libc = "0.2" +snap = "1" +tracing = "0.1" +memmap = "0.7" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_middle = { path = "../rustc_middle" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_target = { path = "../rustc_target" } +rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +stable_deref_trait = "1.0.0" +rustc_ast = { path = "../rustc_ast" } +rustc_expand = { path = "../rustc_expand" } +rustc_span = { path = "../rustc_span" } +rustc_session = { path = "../rustc_session" } + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] } diff --git a/src/librustc_metadata/creader.rs b/compiler/rustc_metadata/src/creader.rs index 7562da6d782..7562da6d782 100644 --- a/src/librustc_metadata/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs diff --git a/src/librustc_metadata/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index f7454da90a3..f7454da90a3 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs diff --git a/src/librustc_metadata/dynamic_lib.rs b/compiler/rustc_metadata/src/dynamic_lib.rs index bdb53e3f75a..bdb53e3f75a 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/compiler/rustc_metadata/src/dynamic_lib.rs diff --git a/src/librustc_metadata/dynamic_lib/tests.rs b/compiler/rustc_metadata/src/dynamic_lib/tests.rs index 7090bbf61c7..7090bbf61c7 100644 --- a/src/librustc_metadata/dynamic_lib/tests.rs +++ b/compiler/rustc_metadata/src/dynamic_lib/tests.rs diff --git a/src/librustc_metadata/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index 8675197656a..8675197656a 100644 --- a/src/librustc_metadata/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs diff --git a/src/librustc_metadata/lib.rs b/compiler/rustc_metadata/src/lib.rs index 85490f5f6e9..85490f5f6e9 100644 --- a/src/librustc_metadata/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs diff --git a/src/librustc_metadata/link_args.rs b/compiler/rustc_metadata/src/link_args.rs index d8f16796083..d8f16796083 100644 --- a/src/librustc_metadata/link_args.rs +++ b/compiler/rustc_metadata/src/link_args.rs diff --git a/src/librustc_metadata/locator.rs b/compiler/rustc_metadata/src/locator.rs index 0869ec28367..0869ec28367 100644 --- a/src/librustc_metadata/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs diff --git a/src/librustc_metadata/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 3976475cb06..3976475cb06 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs diff --git a/src/librustc_metadata/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 43d76e9fdb4..43d76e9fdb4 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 36ff65fc5eb..36ff65fc5eb 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs diff --git a/src/librustc_metadata/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 509ef1caf1a..509ef1caf1a 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs diff --git a/src/librustc_metadata/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1ba5962d119..1ba5962d119 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs diff --git a/src/librustc_metadata/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 03bd4170ea9..03bd4170ea9 100644 --- a/src/librustc_metadata/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml new file mode 100644 index 00000000000..5a82cbf2997 --- /dev/null +++ b/compiler/rustc_middle/Cargo.toml @@ -0,0 +1,33 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_middle" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_arena = { path = "../rustc_arena" } +bitflags = "1.2.1" +tracing = "0.1" +rustc-rayon-core = "0.3.0" +polonius-engine = "0.12.0" +rustc_apfloat = { path = "../rustc_apfloat" } +rustc_attr = { path = "../rustc_attr" } +rustc_feature = { path = "../rustc_feature" } +rustc_hir = { path = "../rustc_hir" } +rustc_target = { path = "../rustc_target" } +rustc_macros = { path = "../rustc_macros" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_query_system = { path = "../rustc_query_system" } +rustc_errors = { path = "../rustc_errors" } +rustc_index = { path = "../rustc_index" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +byteorder = { version = "1.3" } +chalk-ir = "0.14.0" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +measureme = "0.7.1" +rustc_session = { path = "../rustc_session" } diff --git a/src/librustc_middle/README.md b/compiler/rustc_middle/README.md index de58f546cd3..de58f546cd3 100644 --- a/src/librustc_middle/README.md +++ b/compiler/rustc_middle/README.md diff --git a/src/librustc_middle/benches/lib.rs b/compiler/rustc_middle/benches/lib.rs index 237751bcbd7..237751bcbd7 100644 --- a/src/librustc_middle/benches/lib.rs +++ b/compiler/rustc_middle/benches/lib.rs diff --git a/src/librustc_middle/arena.rs b/compiler/rustc_middle/src/arena.rs index f6570cc95d2..f6570cc95d2 100644 --- a/src/librustc_middle/arena.rs +++ b/compiler/rustc_middle/src/arena.rs diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index a61b9af9bac..a61b9af9bac 100644 --- a/src/librustc_middle/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs diff --git a/src/librustc_middle/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 66975242798..66975242798 100644 --- a/src/librustc_middle/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs diff --git a/src/librustc_middle/hir/exports.rs b/compiler/rustc_middle/src/hir/exports.rs index be9e38aca65..be9e38aca65 100644 --- a/src/librustc_middle/hir/exports.rs +++ b/compiler/rustc_middle/src/hir/exports.rs diff --git a/src/librustc_middle/hir/map/blocks.rs b/compiler/rustc_middle/src/hir/map/blocks.rs index 6f572a4875f..6f572a4875f 100644 --- a/src/librustc_middle/hir/map/blocks.rs +++ b/compiler/rustc_middle/src/hir/map/blocks.rs diff --git a/src/librustc_middle/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index dce06a5f7ee..dce06a5f7ee 100644 --- a/src/librustc_middle/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs diff --git a/src/librustc_middle/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 1e57411f9c5..1e57411f9c5 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs diff --git a/src/librustc_middle/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ae3b30217cc..ae3b30217cc 100644 --- a/src/librustc_middle/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs diff --git a/src/librustc_middle/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index bcb56fae170..bcb56fae170 100644 --- a/src/librustc_middle/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs diff --git a/src/librustc_middle/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs index 084fe4cfa16..084fe4cfa16 100644 --- a/src/librustc_middle/ich/hcx.rs +++ b/compiler/rustc_middle/src/ich/hcx.rs diff --git a/src/librustc_middle/ich/impls_hir.rs b/compiler/rustc_middle/src/ich/impls_hir.rs index c2d177b69b6..c2d177b69b6 100644 --- a/src/librustc_middle/ich/impls_hir.rs +++ b/compiler/rustc_middle/src/ich/impls_hir.rs diff --git a/src/librustc_middle/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs index e3d4655831b..e3d4655831b 100644 --- a/src/librustc_middle/ich/impls_syntax.rs +++ b/compiler/rustc_middle/src/ich/impls_syntax.rs diff --git a/src/librustc_middle/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index 8f15c99f951..8f15c99f951 100644 --- a/src/librustc_middle/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs diff --git a/src/librustc_middle/ich/mod.rs b/compiler/rustc_middle/src/ich/mod.rs index c8fb2bf39cc..c8fb2bf39cc 100644 --- a/src/librustc_middle/ich/mod.rs +++ b/compiler/rustc_middle/src/ich/mod.rs diff --git a/src/librustc_middle/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 1e15ae49a0c..1e15ae49a0c 100644 --- a/src/librustc_middle/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs diff --git a/src/librustc_middle/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs index 497d3811f28..497d3811f28 100644 --- a/src/librustc_middle/infer/mod.rs +++ b/compiler/rustc_middle/src/infer/mod.rs diff --git a/src/librustc_middle/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 2580ac6bebd..2580ac6bebd 100644 --- a/src/librustc_middle/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs diff --git a/src/librustc_middle/lib.rs b/compiler/rustc_middle/src/lib.rs index 1b2dea8a378..a675aae5b17 100644 --- a/src/librustc_middle/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -38,6 +38,7 @@ #![feature(exhaustive_patterns)] #![feature(extern_types)] #![feature(nll)] +#![feature(once_cell)] #![feature(option_expect_none)] #![feature(or_patterns)] #![feature(min_specialization)] diff --git a/src/librustc_middle/lint.rs b/compiler/rustc_middle/src/lint.rs index 25e5379881e..25e5379881e 100644 --- a/src/librustc_middle/lint.rs +++ b/compiler/rustc_middle/src/lint.rs diff --git a/src/librustc_middle/macros.rs b/compiler/rustc_middle/src/macros.rs index a5482b7bdcf..a5482b7bdcf 100644 --- a/src/librustc_middle/macros.rs +++ b/compiler/rustc_middle/src/macros.rs diff --git a/src/librustc_middle/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 62a6198b9b4..62a6198b9b4 100644 --- a/src/librustc_middle/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs diff --git a/src/librustc_middle/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs index 1af1d581817..1af1d581817 100644 --- a/src/librustc_middle/middle/cstore.rs +++ b/compiler/rustc_middle/src/middle/cstore.rs diff --git a/src/librustc_middle/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs index e079843bfbc..e079843bfbc 100644 --- a/src/librustc_middle/middle/dependency_format.rs +++ b/compiler/rustc_middle/src/middle/dependency_format.rs diff --git a/src/librustc_middle/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 276e45ce99b..276e45ce99b 100644 --- a/src/librustc_middle/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs diff --git a/src/librustc_middle/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 7194a035e89..7194a035e89 100644 --- a/src/librustc_middle/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs diff --git a/src/librustc_middle/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index def9e5ebb52..def9e5ebb52 100644 --- a/src/librustc_middle/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs diff --git a/src/librustc_middle/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 9bc9ca6707a..9bc9ca6707a 100644 --- a/src/librustc_middle/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs diff --git a/src/librustc_middle/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 4756e83b5e9..4756e83b5e9 100644 --- a/src/librustc_middle/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs diff --git a/src/librustc_middle/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 4c6ac820604..4c6ac820604 100644 --- a/src/librustc_middle/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs diff --git a/src/librustc_middle/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 3d0144e9c8a..3d0144e9c8a 100644 --- a/src/librustc_middle/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs diff --git a/src/librustc_middle/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index b32eebbb11e..b32eebbb11e 100644 --- a/src/librustc_middle/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs diff --git a/src/librustc_middle/mir/coverage/mod.rs b/compiler/rustc_middle/src/mir/coverage/mod.rs index ce311c2ee52..ce311c2ee52 100644 --- a/src/librustc_middle/mir/coverage/mod.rs +++ b/compiler/rustc_middle/src/mir/coverage/mod.rs diff --git a/src/librustc_middle/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 505939d56ed..505939d56ed 100644 --- a/src/librustc_middle/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs diff --git a/src/librustc_middle/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 059925088ce..059925088ce 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs diff --git a/src/librustc_middle/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 0dc3d6e344a..0dc3d6e344a 100644 --- a/src/librustc_middle/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs diff --git a/src/librustc_middle/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index e3d5a085613..e3d5a085613 100644 --- a/src/librustc_middle/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs diff --git a/src/librustc_middle/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index dcc1f8b1a4b..dcc1f8b1a4b 100644 --- a/src/librustc_middle/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs diff --git a/src/librustc_middle/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 7d6ff3eb5c1..7d6ff3eb5c1 100644 --- a/src/librustc_middle/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs diff --git a/src/librustc_middle/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 785a7f0c51a..785a7f0c51a 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs diff --git a/src/librustc_middle/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 0d5f6619df5..79e2c5aac23 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -1,6 +1,5 @@ use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId}; use crate::ich::{NodeIdHashingMode, StableHashingContext}; -use crate::ty::print::obsolete::DefPathBasedNames; use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; use rustc_attr::InlineAttr; use rustc_data_structures::base_n; @@ -86,7 +85,7 @@ impl<'tcx> MonoItem<'tcx> { .debugging_opts .inline_in_all_cgus .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No) - && tcx.sess.opts.cg.link_dead_code != Some(true); + && !tcx.sess.link_dead_code(); match *self { MonoItem::Fn(ref instance) => { @@ -171,30 +170,6 @@ impl<'tcx> MonoItem<'tcx> { !tcx.subst_and_check_impossible_predicates((def_id, &substs)) } - pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String { - return match *self { - MonoItem::Fn(instance) => to_string_internal(tcx, "fn ", instance, debug), - MonoItem::Static(def_id) => { - let instance = Instance::new(def_id, tcx.intern_substs(&[])); - to_string_internal(tcx, "static ", instance, debug) - } - MonoItem::GlobalAsm(..) => "global_asm".to_string(), - }; - - fn to_string_internal<'tcx>( - tcx: TyCtxt<'tcx>, - prefix: &str, - instance: Instance<'tcx>, - debug: bool, - ) -> String { - let mut result = String::with_capacity(32); - result.push_str(prefix); - let printer = DefPathBasedNames::new(tcx, false, false); - printer.push_instance_as_string(instance, &mut result, debug); - result - } - } - pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> { match *self { MonoItem::Fn(Instance { def, .. }) => { @@ -229,6 +204,18 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> { } } +impl<'tcx> fmt::Display for MonoItem<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + MonoItem::Fn(instance) => write!(f, "fn {}", instance), + MonoItem::Static(def_id) => { + write!(f, "static {}", Instance::new(def_id, InternalSubsts::empty())) + } + MonoItem::GlobalAsm(..) => write!(f, "global_asm"), + } + } +} + pub struct CodegenUnit<'tcx> { /// A name for this CGU. Incremental compilation requires that /// name be unique amongst **all** crates. Therefore, it should diff --git a/src/librustc_middle/mir/predecessors.rs b/compiler/rustc_middle/src/mir/predecessors.rs index b16a1d53fff..b16a1d53fff 100644 --- a/src/librustc_middle/mir/predecessors.rs +++ b/compiler/rustc_middle/src/mir/predecessors.rs diff --git a/src/librustc_middle/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 0878e9313d8..0878e9313d8 100644 --- a/src/librustc_middle/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs diff --git a/src/librustc_middle/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index efcd41e5c18..efcd41e5c18 100644 --- a/src/librustc_middle/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs diff --git a/src/librustc_middle/mir/terminator/mod.rs b/compiler/rustc_middle/src/mir/terminator/mod.rs index fcfd648c2b7..fcfd648c2b7 100644 --- a/src/librustc_middle/mir/terminator/mod.rs +++ b/compiler/rustc_middle/src/mir/terminator/mod.rs diff --git a/src/librustc_middle/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 36e277d1a88..36e277d1a88 100644 --- a/src/librustc_middle/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs diff --git a/src/librustc_middle/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 6bb6abe0289..6bb6abe0289 100644 --- a/src/librustc_middle/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs diff --git a/src/librustc_middle/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 6515ae31b46..6515ae31b46 100644 --- a/src/librustc_middle/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs diff --git a/src/librustc_middle/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e05752f08f6..e05752f08f6 100644 --- a/src/librustc_middle/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs diff --git a/src/librustc_middle/tests.rs b/compiler/rustc_middle/src/tests.rs index 757e0bd3bfb..757e0bd3bfb 100644 --- a/src/librustc_middle/tests.rs +++ b/compiler/rustc_middle/src/tests.rs diff --git a/src/librustc_middle/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs index 405af8cb240..405af8cb240 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/compiler/rustc_middle/src/traits/chalk.rs diff --git a/src/librustc_middle/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f86403fa502..f86403fa502 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs diff --git a/src/librustc_middle/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 4b7663e9ade..4b7663e9ade 100644 --- a/src/librustc_middle/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs diff --git a/src/librustc_middle/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 6ad514c6be2..6ad514c6be2 100644 --- a/src/librustc_middle/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs diff --git a/src/librustc_middle/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 969404c68ca..969404c68ca 100644 --- a/src/librustc_middle/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs diff --git a/src/librustc_middle/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index d73fc628ceb..d73fc628ceb 100644 --- a/src/librustc_middle/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs diff --git a/src/librustc_middle/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 4693a2f66fb..4693a2f66fb 100644 --- a/src/librustc_middle/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs diff --git a/src/librustc_middle/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 6a9bb8d6c28..6a9bb8d6c28 100644 --- a/src/librustc_middle/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs diff --git a/src/librustc_middle/ty/binding.rs b/compiler/rustc_middle/src/ty/binding.rs index 3237147c8ba..3237147c8ba 100644 --- a/src/librustc_middle/ty/binding.rs +++ b/compiler/rustc_middle/src/ty/binding.rs diff --git a/src/librustc_middle/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 79a3008c364..79a3008c364 100644 --- a/src/librustc_middle/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs diff --git a/src/librustc_middle/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 291648869fb..291648869fb 100644 --- a/src/librustc_middle/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs diff --git a/src/librustc_middle/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 64faacc1c0b..64faacc1c0b 100644 --- a/src/librustc_middle/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs diff --git a/src/librustc_middle/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index ced0429deab..ced0429deab 100644 --- a/src/librustc_middle/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs diff --git a/src/librustc_middle/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ede28522000..ede28522000 100644 --- a/src/librustc_middle/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs diff --git a/src/librustc_middle/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 18ae744cb1e..5819c774bc2 100644 --- a/src/librustc_middle/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -34,6 +34,7 @@ use rustc_data_structures::stable_hasher::{ hash_stable_hashmap, HashStable, StableHasher, StableVec, }; use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal}; +use rustc_data_structures::unhash::UnhashMap; use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -935,7 +936,7 @@ pub struct GlobalCtxt<'tcx> { /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate /// as well as all upstream crates. Only populated in incremental mode. - pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>, + pub def_path_hash_to_def_id: Option<UnhashMap<DefPathHash, DefId>>, pub queries: query::Queries<'tcx>, @@ -1104,7 +1105,7 @@ impl<'tcx> TyCtxt<'tcx> { let def_path_hash_to_def_id = if s.opts.build_dep_graph() { let capacity = definitions.def_path_table().num_def_ids() + crates.iter().map(|cnum| cstore.num_def_ids(*cnum)).sum::<usize>(); - let mut map = FxHashMap::with_capacity_and_hasher(capacity, Default::default()); + let mut map = UnhashMap::with_capacity_and_hasher(capacity, Default::default()); map.extend(definitions.def_path_table().all_def_path_hashes_and_def_ids(LOCAL_CRATE)); for cnum in &crates { diff --git a/src/librustc_middle/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index b22727bdd75..b22727bdd75 100644 --- a/src/librustc_middle/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs diff --git a/src/librustc_middle/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 48d0fc1839e..48d0fc1839e 100644 --- a/src/librustc_middle/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs diff --git a/src/librustc_middle/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 1963881626e..1963881626e 100644 --- a/src/librustc_middle/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs diff --git a/src/librustc_middle/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 1bee2d60f75..1bee2d60f75 100644 --- a/src/librustc_middle/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs diff --git a/src/librustc_middle/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 27f50c240db..27f50c240db 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs diff --git a/src/librustc_middle/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 492f8ce9ef1..492f8ce9ef1 100644 --- a/src/librustc_middle/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs diff --git a/src/librustc_middle/ty/inhabitedness/def_id_forest.rs b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs index ee6b06a1cc8..ee6b06a1cc8 100644 --- a/src/librustc_middle/ty/inhabitedness/def_id_forest.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs diff --git a/src/librustc_middle/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index d1b5eed921b..d1b5eed921b 100644 --- a/src/librustc_middle/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs diff --git a/src/librustc_middle/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8e08fe4b87b..8e08fe4b87b 100644 --- a/src/librustc_middle/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs diff --git a/src/librustc_middle/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 08bd131565b..08bd131565b 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs diff --git a/src/librustc_middle/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 83a2bdf90f9..83a2bdf90f9 100644 --- a/src/librustc_middle/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs diff --git a/src/librustc_middle/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b6300a40b0d..b6300a40b0d 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs diff --git a/src/librustc_middle/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 48a62b64604..48a62b64604 100644 --- a/src/librustc_middle/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs diff --git a/src/librustc_middle/ty/outlives.rs b/compiler/rustc_middle/src/ty/outlives.rs index 1a8693b8df7..1a8693b8df7 100644 --- a/src/librustc_middle/ty/outlives.rs +++ b/compiler/rustc_middle/src/ty/outlives.rs diff --git a/src/librustc_middle/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 6c8f23c139f..bfeef7892c3 100644 --- a/src/librustc_middle/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -9,8 +9,6 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; mod pretty; pub use self::pretty::*; -pub mod obsolete; - // FIXME(eddyb) false positive, the lifetime parameters are used with `P: Printer<...>`. #[allow(unused_lifetimes)] pub trait Print<'tcx, P> { diff --git a/src/librustc_middle/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 999a1d52a26..999a1d52a26 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs diff --git a/src/librustc_middle/ty/query/README.md b/compiler/rustc_middle/src/ty/query/README.md index 8ec07b9fdeb..8ec07b9fdeb 100644 --- a/src/librustc_middle/ty/query/README.md +++ b/compiler/rustc_middle/src/ty/query/README.md diff --git a/src/librustc_middle/ty/query/job.rs b/compiler/rustc_middle/src/ty/query/job.rs index bd2e7747b7d..bd2e7747b7d 100644 --- a/src/librustc_middle/ty/query/job.rs +++ b/compiler/rustc_middle/src/ty/query/job.rs diff --git a/src/librustc_middle/ty/query/keys.rs b/compiler/rustc_middle/src/ty/query/keys.rs index 3f7a20bba2b..3f7a20bba2b 100644 --- a/src/librustc_middle/ty/query/keys.rs +++ b/compiler/rustc_middle/src/ty/query/keys.rs diff --git a/src/librustc_middle/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index ee9b203b151..ee9b203b151 100644 --- a/src/librustc_middle/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs diff --git a/src/librustc_middle/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs index dcfb8d31430..dcfb8d31430 100644 --- a/src/librustc_middle/ty/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs diff --git a/src/librustc_middle/ty/query/plumbing.rs b/compiler/rustc_middle/src/ty/query/plumbing.rs index f3fa3634026..f3fa3634026 100644 --- a/src/librustc_middle/ty/query/plumbing.rs +++ b/compiler/rustc_middle/src/ty/query/plumbing.rs diff --git a/src/librustc_middle/ty/query/profiling_support.rs b/compiler/rustc_middle/src/ty/query/profiling_support.rs index 9b1837356e3..9b1837356e3 100644 --- a/src/librustc_middle/ty/query/profiling_support.rs +++ b/compiler/rustc_middle/src/ty/query/profiling_support.rs diff --git a/src/librustc_middle/ty/query/stats.rs b/compiler/rustc_middle/src/ty/query/stats.rs index b496bf839ab..b496bf839ab 100644 --- a/src/librustc_middle/ty/query/stats.rs +++ b/compiler/rustc_middle/src/ty/query/stats.rs diff --git a/src/librustc_middle/ty/query/values.rs b/compiler/rustc_middle/src/ty/query/values.rs index f28b0f499f0..f28b0f499f0 100644 --- a/src/librustc_middle/ty/query/values.rs +++ b/compiler/rustc_middle/src/ty/query/values.rs diff --git a/src/librustc_middle/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index ae2820b460f..ae2820b460f 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs diff --git a/src/librustc_middle/ty/steal.rs b/compiler/rustc_middle/src/ty/steal.rs index 224e76845d7..224e76845d7 100644 --- a/src/librustc_middle/ty/steal.rs +++ b/compiler/rustc_middle/src/ty/steal.rs diff --git a/src/librustc_middle/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 605e3545dea..605e3545dea 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs diff --git a/src/librustc_middle/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c1f354c7a15..c1f354c7a15 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs diff --git a/src/librustc_middle/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index acd58ab7f96..acd58ab7f96 100644 --- a/src/librustc_middle/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs diff --git a/src/librustc_middle/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 86fe3ac3751..86fe3ac3751 100644 --- a/src/librustc_middle/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs diff --git a/src/librustc_middle/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 63d4dcca080..63d4dcca080 100644 --- a/src/librustc_middle/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs diff --git a/src/librustc_middle/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 82c649b8f54..ece8da7e51e 100644 --- a/src/librustc_middle/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -55,7 +55,7 @@ impl GenericArg<'tcx> { /// that appear in `self`, it does not descend into the fields of /// structs or variants. For example: /// - /// ```notrust + /// ```text /// isize => { isize } /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize } /// [isize] => { [isize], isize } @@ -80,7 +80,7 @@ impl<'tcx> super::TyS<'tcx> { /// that appear in `self`, it does not descend into the fields of /// structs or variants. For example: /// - /// ```notrust + /// ```text /// isize => { isize } /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize } /// [isize] => { [isize], isize } diff --git a/src/librustc_middle/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index 0903ef50898..0903ef50898 100644 --- a/src/librustc_middle/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs diff --git a/src/librustc_middle/util/common.rs b/compiler/rustc_middle/src/util/common.rs index 1e09702bf27..1e09702bf27 100644 --- a/src/librustc_middle/util/common.rs +++ b/compiler/rustc_middle/src/util/common.rs diff --git a/src/librustc_middle/util/common/tests.rs b/compiler/rustc_middle/src/util/common/tests.rs index 9a9fb203c62..9a9fb203c62 100644 --- a/src/librustc_middle/util/common/tests.rs +++ b/compiler/rustc_middle/src/util/common/tests.rs diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml new file mode 100644 index 00000000000..6b0412ece7a --- /dev/null +++ b/compiler/rustc_mir/Cargo.toml @@ -0,0 +1,33 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_mir" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +either = "1.5.0" +rustc_graphviz = { path = "../rustc_graphviz" } +itertools = "0.8" +tracing = "0.1" +log_settings = "0.1.1" +polonius-engine = "0.12.0" +rustc_middle = { path = "../rustc_middle" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_infer = { path = "../rustc_infer" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } +rustc_target = { path = "../rustc_target" } +rustc_trait_selection = { path = "../rustc_trait_selection" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +rustc_apfloat = { path = "../rustc_apfloat" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/compiler/rustc_mir/src/borrow_check/borrow_set.rs index b4299fbc5a1..b4299fbc5a1 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/compiler/rustc_mir/src/borrow_check/borrow_set.rs diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/compiler/rustc_mir/src/borrow_check/constraint_generation.rs index 33b09dcb888..33b09dcb888 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/compiler/rustc_mir/src/borrow_check/constraint_generation.rs diff --git a/src/librustc_mir/borrow_check/constraints/graph.rs b/compiler/rustc_mir/src/borrow_check/constraints/graph.rs index f3f6b8c10da..f3f6b8c10da 100644 --- a/src/librustc_mir/borrow_check/constraints/graph.rs +++ b/compiler/rustc_mir/src/borrow_check/constraints/graph.rs diff --git a/src/librustc_mir/borrow_check/constraints/mod.rs b/compiler/rustc_mir/src/borrow_check/constraints/mod.rs index 3772b7d8f98..3772b7d8f98 100644 --- a/src/librustc_mir/borrow_check/constraints/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/constraints/mod.rs diff --git a/src/librustc_mir/borrow_check/def_use.rs b/compiler/rustc_mir/src/borrow_check/def_use.rs index 6574e584406..6574e584406 100644 --- a/src/librustc_mir/borrow_check/def_use.rs +++ b/compiler/rustc_mir/src/borrow_check/def_use.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 9076dbccb52..9076dbccb52 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index b591b938b5a..b591b938b5a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/find_use.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/find_use.rs index 8d8cdfb5293..8d8cdfb5293 100644 --- a/src/librustc_mir/borrow_check/diagnostics/find_use.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/find_use.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index dfaa75d9f23..dfaa75d9f23 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs index 1c8da212f10..1c8da212f10 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs index d26436ff1de..d26436ff1de 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs index a775fa59c1b..a775fa59c1b 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/outlives_suggestion.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs index a0d99ac33c0..a0d99ac33c0 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index 2603b1e048d..2603b1e048d 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/var_name.rs index a850b85e9bb..a850b85e9bb 100644 --- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/var_name.rs diff --git a/src/librustc_mir/borrow_check/facts.rs b/compiler/rustc_mir/src/borrow_check/facts.rs index 6d6b94ecf64..6d6b94ecf64 100644 --- a/src/librustc_mir/borrow_check/facts.rs +++ b/compiler/rustc_mir/src/borrow_check/facts.rs diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs index c84ccafaff5..c84ccafaff5 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs diff --git a/src/librustc_mir/borrow_check/location.rs b/compiler/rustc_mir/src/borrow_check/location.rs index 375ff72679f..375ff72679f 100644 --- a/src/librustc_mir/borrow_check/location.rs +++ b/compiler/rustc_mir/src/borrow_check/location.rs diff --git a/src/librustc_mir/borrow_check/member_constraints.rs b/compiler/rustc_mir/src/borrow_check/member_constraints.rs index d4baa5d809a..d4baa5d809a 100644 --- a/src/librustc_mir/borrow_check/member_constraints.rs +++ b/compiler/rustc_mir/src/borrow_check/member_constraints.rs diff --git a/src/librustc_mir/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 86908eaabd1..86908eaabd1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs diff --git a/src/librustc_mir/borrow_check/nll.rs b/compiler/rustc_mir/src/borrow_check/nll.rs index 66a17cba6bb..66a17cba6bb 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/compiler/rustc_mir/src/borrow_check/nll.rs diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/compiler/rustc_mir/src/borrow_check/path_utils.rs index 934729553a7..934729553a7 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/compiler/rustc_mir/src/borrow_check/path_utils.rs diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/compiler/rustc_mir/src/borrow_check/place_ext.rs index cadf1ebf1b7..cadf1ebf1b7 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/compiler/rustc_mir/src/borrow_check/place_ext.rs diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/compiler/rustc_mir/src/borrow_check/places_conflict.rs index 246e4826e0e..246e4826e0e 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/compiler/rustc_mir/src/borrow_check/places_conflict.rs diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/compiler/rustc_mir/src/borrow_check/prefixes.rs index a2475e0ff29..a2475e0ff29 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/compiler/rustc_mir/src/borrow_check/prefixes.rs diff --git a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs b/compiler/rustc_mir/src/borrow_check/region_infer/dump_mir.rs index d6e48deb031..d6e48deb031 100644 --- a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/dump_mir.rs diff --git a/src/librustc_mir/borrow_check/region_infer/graphviz.rs b/compiler/rustc_mir/src/borrow_check/region_infer/graphviz.rs index a272e922a50..a272e922a50 100644 --- a/src/librustc_mir/borrow_check/region_infer/graphviz.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/graphviz.rs diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs index 081125cb625..081125cb625 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs diff --git a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs index 325dca8c8ca..325dca8c8ca 100644 --- a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs diff --git a/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs b/compiler/rustc_mir/src/borrow_check/region_infer/reverse_sccs.rs index 5d345a6e63d..5d345a6e63d 100644 --- a/src/librustc_mir/borrow_check/region_infer/reverse_sccs.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/reverse_sccs.rs diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/compiler/rustc_mir/src/borrow_check/region_infer/values.rs index 8a5a600cfdd..8a5a600cfdd 100644 --- a/src/librustc_mir/borrow_check/region_infer/values.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/values.rs diff --git a/src/librustc_mir/borrow_check/renumber.rs b/compiler/rustc_mir/src/borrow_check/renumber.rs index 5df033b48c1..5df033b48c1 100644 --- a/src/librustc_mir/borrow_check/renumber.rs +++ b/compiler/rustc_mir/src/borrow_check/renumber.rs diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs index 711271a63fb..711271a63fb 100644 --- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs index beee3181256..beee3181256 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs diff --git a/src/librustc_mir/borrow_check/type_check/input_output.rs b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs index 4846ef06a8b..4846ef06a8b 100644 --- a/src/librustc_mir/borrow_check/type_check/input_output.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs diff --git a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs index 995e3a60a0c..995e3a60a0c 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs diff --git a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/mod.rs index bddcd34ed3e..bddcd34ed3e 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/mod.rs diff --git a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/polonius.rs index d285098c52a..d285098c52a 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/polonius.rs diff --git a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs index f04736e04a0..f04736e04a0 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index 69c4f633770..69c4f633770 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs diff --git a/src/librustc_mir/borrow_check/type_check/relate_tys.rs b/compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs index 91b1a1fbd97..91b1a1fbd97 100644 --- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index 9dfc67bcf67..9dfc67bcf67 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/compiler/rustc_mir/src/borrow_check/used_muts.rs index e027056842d..e027056842d 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/compiler/rustc_mir/src/borrow_check/used_muts.rs diff --git a/src/librustc_mir/const_eval/error.rs b/compiler/rustc_mir/src/const_eval/error.rs index 044d27a6a9d..044d27a6a9d 100644 --- a/src/librustc_mir/const_eval/error.rs +++ b/compiler/rustc_mir/src/const_eval/error.rs diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index 291b42c12d7..291b42c12d7 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/compiler/rustc_mir/src/const_eval/fn_queries.rs index 9ef63b3322d..9ef63b3322d 100644 --- a/src/librustc_mir/const_eval/fn_queries.rs +++ b/compiler/rustc_mir/src/const_eval/fn_queries.rs diff --git a/src/librustc_mir/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs index b0357c508a3..b0357c508a3 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/compiler/rustc_mir/src/const_eval/machine.rs diff --git a/src/librustc_mir/const_eval/mod.rs b/compiler/rustc_mir/src/const_eval/mod.rs index e7eeb4b4de4..e7eeb4b4de4 100644 --- a/src/librustc_mir/const_eval/mod.rs +++ b/compiler/rustc_mir/src/const_eval/mod.rs diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/compiler/rustc_mir/src/dataflow/drop_flag_effects.rs index 707e136678e..707e136678e 100644 --- a/src/librustc_mir/dataflow/drop_flag_effects.rs +++ b/compiler/rustc_mir/src/dataflow/drop_flag_effects.rs diff --git a/src/librustc_mir/dataflow/framework/cursor.rs b/compiler/rustc_mir/src/dataflow/framework/cursor.rs index 4f5930dc3f5..4f5930dc3f5 100644 --- a/src/librustc_mir/dataflow/framework/cursor.rs +++ b/compiler/rustc_mir/src/dataflow/framework/cursor.rs diff --git a/src/librustc_mir/dataflow/framework/direction.rs b/compiler/rustc_mir/src/dataflow/framework/direction.rs index 4512ae96c08..4512ae96c08 100644 --- a/src/librustc_mir/dataflow/framework/direction.rs +++ b/compiler/rustc_mir/src/dataflow/framework/direction.rs diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/compiler/rustc_mir/src/dataflow/framework/engine.rs index b703852b1de..b703852b1de 100644 --- a/src/librustc_mir/dataflow/framework/engine.rs +++ b/compiler/rustc_mir/src/dataflow/framework/engine.rs diff --git a/src/librustc_mir/dataflow/framework/graphviz.rs b/compiler/rustc_mir/src/dataflow/framework/graphviz.rs index 896616a2175..896616a2175 100644 --- a/src/librustc_mir/dataflow/framework/graphviz.rs +++ b/compiler/rustc_mir/src/dataflow/framework/graphviz.rs diff --git a/src/librustc_mir/dataflow/framework/mod.rs b/compiler/rustc_mir/src/dataflow/framework/mod.rs index a21bbacb467..a21bbacb467 100644 --- a/src/librustc_mir/dataflow/framework/mod.rs +++ b/compiler/rustc_mir/src/dataflow/framework/mod.rs diff --git a/src/librustc_mir/dataflow/framework/tests.rs b/compiler/rustc_mir/src/dataflow/framework/tests.rs index 9349f5133a5..9349f5133a5 100644 --- a/src/librustc_mir/dataflow/framework/tests.rs +++ b/compiler/rustc_mir/src/dataflow/framework/tests.rs diff --git a/src/librustc_mir/dataflow/framework/visitor.rs b/compiler/rustc_mir/src/dataflow/framework/visitor.rs index 257f3cb9a6d..257f3cb9a6d 100644 --- a/src/librustc_mir/dataflow/framework/visitor.rs +++ b/compiler/rustc_mir/src/dataflow/framework/visitor.rs diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/compiler/rustc_mir/src/dataflow/impls/borrowed_locals.rs index a3fc51cad65..a3fc51cad65 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/borrowed_locals.rs diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/compiler/rustc_mir/src/dataflow/impls/borrows.rs index aeb7ffe3e3b..aeb7ffe3e3b 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/compiler/rustc_mir/src/dataflow/impls/borrows.rs diff --git a/src/librustc_mir/dataflow/impls/init_locals.rs b/compiler/rustc_mir/src/dataflow/impls/init_locals.rs index 0e7cd1bb0e4..0e7cd1bb0e4 100644 --- a/src/librustc_mir/dataflow/impls/init_locals.rs +++ b/compiler/rustc_mir/src/dataflow/impls/init_locals.rs diff --git a/src/librustc_mir/dataflow/impls/liveness.rs b/compiler/rustc_mir/src/dataflow/impls/liveness.rs index 784b0bd9293..784b0bd9293 100644 --- a/src/librustc_mir/dataflow/impls/liveness.rs +++ b/compiler/rustc_mir/src/dataflow/impls/liveness.rs diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/compiler/rustc_mir/src/dataflow/impls/mod.rs index 8975faec487..8975faec487 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/compiler/rustc_mir/src/dataflow/impls/mod.rs diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/compiler/rustc_mir/src/dataflow/impls/storage_liveness.rs index 21623e3cad5..21623e3cad5 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/compiler/rustc_mir/src/dataflow/impls/storage_liveness.rs diff --git a/src/librustc_mir/dataflow/mod.rs b/compiler/rustc_mir/src/dataflow/mod.rs index a0c24636059..a0c24636059 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/compiler/rustc_mir/src/dataflow/mod.rs diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/compiler/rustc_mir/src/dataflow/move_paths/abs_domain.rs index 28936274baa..28936274baa 100644 --- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/abs_domain.rs diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs index e088dc6a954..e088dc6a954 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/compiler/rustc_mir/src/dataflow/move_paths/mod.rs index d66d2625d78..d66d2625d78 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/mod.rs diff --git a/src/librustc_mir/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index 501a5bcddb3..501a5bcddb3 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs diff --git a/src/librustc_mir/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 525da87463a..525da87463a 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs diff --git a/src/librustc_mir/interpret/intern.rs b/compiler/rustc_mir/src/interpret/intern.rs index 606be7cad2b..606be7cad2b 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/compiler/rustc_mir/src/interpret/intern.rs diff --git a/src/librustc_mir/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index b37dcd42f4c..b37dcd42f4c 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs index d9be28cf9db..d9be28cf9db 100644 --- a/src/librustc_mir/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics/caller_location.rs diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs index 379117f3b84..379117f3b84 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics/type_name.rs diff --git a/src/librustc_mir/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs index 3718da1723b..3718da1723b 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/compiler/rustc_mir/src/interpret/machine.rs diff --git a/src/librustc_mir/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index d4be2ce0568..d4be2ce0568 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/compiler/rustc_mir/src/interpret/memory.rs diff --git a/src/librustc_mir/interpret/mod.rs b/compiler/rustc_mir/src/interpret/mod.rs index a931b0bbe97..a931b0bbe97 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/compiler/rustc_mir/src/interpret/mod.rs diff --git a/src/librustc_mir/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 0b58caef54d..0b58caef54d 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs diff --git a/src/librustc_mir/interpret/operator.rs b/compiler/rustc_mir/src/interpret/operator.rs index 30c40b8fde9..30c40b8fde9 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/compiler/rustc_mir/src/interpret/operator.rs diff --git a/src/librustc_mir/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 6ba6103b311..6ba6103b311 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs diff --git a/src/librustc_mir/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs index 156da84f291..156da84f291 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/compiler/rustc_mir/src/interpret/step.rs diff --git a/src/librustc_mir/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs index 9a036a0f299..9a036a0f299 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/compiler/rustc_mir/src/interpret/terminator.rs diff --git a/src/librustc_mir/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs index 77f4593fa16..77f4593fa16 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/compiler/rustc_mir/src/interpret/traits.rs diff --git a/src/librustc_mir/interpret/util.rs b/compiler/rustc_mir/src/interpret/util.rs index 57c5fc59cc0..57c5fc59cc0 100644 --- a/src/librustc_mir/interpret/util.rs +++ b/compiler/rustc_mir/src/interpret/util.rs diff --git a/src/librustc_mir/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index 9cd20340138..9cd20340138 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs diff --git a/src/librustc_mir/interpret/visitor.rs b/compiler/rustc_mir/src/interpret/visitor.rs index 6c53df40a7c..6c53df40a7c 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/compiler/rustc_mir/src/interpret/visitor.rs diff --git a/src/librustc_mir/lib.rs b/compiler/rustc_mir/src/lib.rs index 2e3b5084635..2e3b5084635 100644 --- a/src/librustc_mir/lib.rs +++ b/compiler/rustc_mir/src/lib.rs diff --git a/src/librustc_mir/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index d379f4ef428..43cac8e5ee6 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -191,7 +191,6 @@ use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Local, Location}; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; -use rustc_middle::ty::print::obsolete::DefPathBasedNames; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable}; use rustc_session::config::EntryFnType; @@ -348,7 +347,7 @@ fn collect_items_rec<'tcx>( // We've been here already, no need to search again. return; } - debug!("BEGIN collect_items_rec({})", starting_point.node.to_string(tcx, true)); + debug!("BEGIN collect_items_rec({})", starting_point.node); let mut neighbors = Vec::new(); let recursion_depth_reset; @@ -397,7 +396,7 @@ fn collect_items_rec<'tcx>( recursion_depths.insert(def_id, depth); } - debug!("END collect_items_rec({})", starting_point.node.to_string(tcx, true)); + debug!("END collect_items_rec({})", starting_point.node); } fn record_accesses<'a, 'tcx: 'a>( @@ -992,7 +991,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { let def_id = self.tcx.hir().local_def_id(item.hir_id); debug!( "RootCollector: ADT drop-glue for {}", - def_id_to_string(self.tcx, def_id) + self.tcx.def_path_str(def_id.to_def_id()) ); let ty = Instance::new(def_id.to_def_id(), InternalSubsts::empty()) @@ -1004,14 +1003,14 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { hir::ItemKind::GlobalAsm(..) => { debug!( "RootCollector: ItemKind::GlobalAsm({})", - def_id_to_string(self.tcx, self.tcx.hir().local_def_id(item.hir_id)) + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.hir_id).to_def_id()) ); self.output.push(dummy_spanned(MonoItem::GlobalAsm(item.hir_id))); } hir::ItemKind::Static(..) => { - let def_id = self.tcx.hir().local_def_id(item.hir_id); - debug!("RootCollector: ItemKind::Static({})", def_id_to_string(self.tcx, def_id)); - self.output.push(dummy_spanned(MonoItem::Static(def_id.to_def_id()))); + let def_id = self.tcx.hir().local_def_id(item.hir_id).to_def_id(); + debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id)); + self.output.push(dummy_spanned(MonoItem::Static(def_id))); } hir::ItemKind::Const(..) => { // const items only generate mono items if they are @@ -1134,7 +1133,7 @@ fn create_mono_items_for_default_impls<'tcx>( debug!( "create_mono_items_for_default_impls(item={})", - def_id_to_string(tcx, impl_def_id) + tcx.def_path_str(impl_def_id.to_def_id()) ); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { @@ -1218,13 +1217,6 @@ fn collect_neighbours<'tcx>( MirNeighborCollector { tcx, body: &body, output, instance }.visit_body(&body); } -fn def_id_to_string(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String { - let mut output = String::new(); - let printer = DefPathBasedNames::new(tcx, false, false); - printer.push_def_path(def_id.to_def_id(), &mut output); - output -} - fn collect_const_value<'tcx>( tcx: TyCtxt<'tcx>, value: ConstValue<'tcx>, diff --git a/src/librustc_mir/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs index edafa00a03a..edafa00a03a 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/mod.rs diff --git a/src/librustc_mir/monomorphize/partitioning/default.rs b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs index b48bae83787..b48bae83787 100644 --- a/src/librustc_mir/monomorphize/partitioning/default.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/default.rs diff --git a/src/librustc_mir/monomorphize/partitioning/merging.rs b/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs index 1787e6df1b9..1787e6df1b9 100644 --- a/src/librustc_mir/monomorphize/partitioning/merging.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/merging.rs diff --git a/src/librustc_mir/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index 9dfbd65e1b1..b45fe0ee010 100644 --- a/src/librustc_mir/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -190,7 +190,7 @@ pub fn partition<'tcx>( // Next we try to make as many symbols "internal" as possible, so LLVM has // more freedom to optimize. - if tcx.sess.opts.cg.link_dead_code != Some(true) { + if !tcx.sess.link_dead_code() { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); partitioner.internalize_symbols(tcx, &mut post_inlining, inlining_map); } @@ -246,7 +246,7 @@ where debug!( " - {} [{:?}] [{}] estimated size {}", - mono_item.to_string(tcx, true), + mono_item, linkage, symbol_hash, mono_item.size_estimate(tcx) @@ -327,7 +327,7 @@ fn collect_and_partition_mono_items<'tcx>( } } None => { - if tcx.sess.opts.cg.link_dead_code == Some(true) { + if tcx.sess.link_dead_code() { MonoItemCollectionMode::Eager } else { MonoItemCollectionMode::Lazy @@ -374,7 +374,7 @@ fn collect_and_partition_mono_items<'tcx>( let mut item_keys: Vec<_> = items .iter() .map(|i| { - let mut output = i.to_string(tcx, false); + let mut output = i.to_string(); output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); diff --git a/src/librustc_mir/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index 69f3288ee39..69f3288ee39 100644 --- a/src/librustc_mir/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs diff --git a/src/librustc_mir/shim.rs b/compiler/rustc_mir/src/shim.rs index 479b6c2a6ca..479b6c2a6ca 100644 --- a/src/librustc_mir/shim.rs +++ b/compiler/rustc_mir/src/shim.rs diff --git a/src/librustc_mir/transform/add_call_guards.rs b/compiler/rustc_mir/src/transform/add_call_guards.rs index 33859115359..33859115359 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/compiler/rustc_mir/src/transform/add_call_guards.rs diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/compiler/rustc_mir/src/transform/add_moves_for_packed_drops.rs index a02d0f65560..a02d0f65560 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir/src/transform/add_moves_for_packed_drops.rs diff --git a/src/librustc_mir/transform/add_retag.rs b/compiler/rustc_mir/src/transform/add_retag.rs index 324289166b9..324289166b9 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/compiler/rustc_mir/src/transform/add_retag.rs diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/compiler/rustc_mir/src/transform/check_consts/mod.rs index 81c1b0b5bd4..81c1b0b5bd4 100644 --- a/src/librustc_mir/transform/check_consts/mod.rs +++ b/compiler/rustc_mir/src/transform/check_consts/mod.rs diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index ea025f208e4..ea025f208e4 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs diff --git a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs index 55075b3ab5e..55075b3ab5e 100644 --- a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_mir/src/transform/check_consts/post_drop_elaboration.rs diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index 445a0230afd..445a0230afd 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/compiler/rustc_mir/src/transform/check_consts/resolver.rs index b8104292aab..b8104292aab 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/compiler/rustc_mir/src/transform/check_consts/resolver.rs diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index e21f314ca15..e21f314ca15 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs diff --git a/src/librustc_mir/transform/check_packed_ref.rs b/compiler/rustc_mir/src/transform/check_packed_ref.rs index 043b2d0d170..043b2d0d170 100644 --- a/src/librustc_mir/transform/check_packed_ref.rs +++ b/compiler/rustc_mir/src/transform/check_packed_ref.rs diff --git a/src/librustc_mir/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index c3e04e698db..c3e04e698db 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs index 3f3d247a829..3f3d247a829 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 56479b047fa..56479b047fa 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs diff --git a/src/librustc_mir/transform/copy_prop.rs b/compiler/rustc_mir/src/transform/copy_prop.rs index ba406c72df8..ba406c72df8 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/compiler/rustc_mir/src/transform/copy_prop.rs diff --git a/src/librustc_mir/transform/deaggregator.rs b/compiler/rustc_mir/src/transform/deaggregator.rs index 66989a90244..66989a90244 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/compiler/rustc_mir/src/transform/deaggregator.rs diff --git a/src/librustc_mir/transform/dump_mir.rs b/compiler/rustc_mir/src/transform/dump_mir.rs index 5ce6f4fa741..5ce6f4fa741 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/compiler/rustc_mir/src/transform/dump_mir.rs diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/compiler/rustc_mir/src/transform/elaborate_drops.rs index 5f193069356..5f193069356 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/compiler/rustc_mir/src/transform/elaborate_drops.rs diff --git a/src/librustc_mir/transform/generator.rs b/compiler/rustc_mir/src/transform/generator.rs index a22075e760a..a22075e760a 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/compiler/rustc_mir/src/transform/generator.rs diff --git a/src/librustc_mir/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 315d4fa9d47..428f4e138c7 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -107,8 +107,14 @@ impl Inliner<'tcx> { // Avoid a cycle here by only using `optimized_mir` only if we have // a lower `HirId` than the callee. This ensures that the callee will // not inline us. This trick only works without incremental compilation. - // So don't do it if that is enabled. - if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id { + // So don't do it if that is enabled. Also avoid inlining into generators, + // since their `optimized_mir` is used for layout computation, which can + // create a cycle, even when no attempt is made to inline the function + // in the other direction. + if !self.tcx.dep_graph.is_fully_enabled() + && self_hir_id < callee_hir_id + && caller_body.generator_kind.is_none() + { self.tcx.optimized_mir(callsite.callee) } else { continue; diff --git a/src/librustc_mir/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs index 7967137e01e..7967137e01e 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/compiler/rustc_mir/src/transform/instcombine.rs diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/compiler/rustc_mir/src/transform/instrument_coverage.rs index f60e6da714a..f60e6da714a 100644 --- a/src/librustc_mir/transform/instrument_coverage.rs +++ b/compiler/rustc_mir/src/transform/instrument_coverage.rs diff --git a/src/librustc_mir/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index c1d574d6ef2..c1d574d6ef2 100644 --- a/src/librustc_mir/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs diff --git a/src/librustc_mir/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index c3a34756122..c3a34756122 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/compiler/rustc_mir/src/transform/no_landing_pads.rs index 1d83733e4cd..1d83733e4cd 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/compiler/rustc_mir/src/transform/no_landing_pads.rs diff --git a/src/librustc_mir/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs index 1f3d7bb7cc6..1f3d7bb7cc6 100644 --- a/src/librustc_mir/transform/nrvo.rs +++ b/compiler/rustc_mir/src/transform/nrvo.rs diff --git a/src/librustc_mir/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index b2dda1caa54..b2dda1caa54 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs index 26db4600a2b..26db4600a2b 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs index 0bad1e5037a..0bad1e5037a 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs diff --git a/src/librustc_mir/transform/required_consts.rs b/compiler/rustc_mir/src/transform/required_consts.rs index a63ab30a68f..a63ab30a68f 100644 --- a/src/librustc_mir/transform/required_consts.rs +++ b/compiler/rustc_mir/src/transform/required_consts.rs diff --git a/src/librustc_mir/transform/rustc_peek.rs b/compiler/rustc_mir/src/transform/rustc_peek.rs index 00d269a4af8..00d269a4af8 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/compiler/rustc_mir/src/transform/rustc_peek.rs diff --git a/src/librustc_mir/transform/simplify.rs b/compiler/rustc_mir/src/transform/simplify.rs index d8995e92abf..d8995e92abf 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/compiler/rustc_mir/src/transform/simplify.rs diff --git a/src/librustc_mir/transform/simplify_branches.rs b/compiler/rustc_mir/src/transform/simplify_branches.rs index 4c30a0946bc..4c30a0946bc 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/compiler/rustc_mir/src/transform/simplify_branches.rs diff --git a/src/librustc_mir/transform/simplify_comparison_integral.rs b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs index a450a75d091..a450a75d091 100644 --- a/src/librustc_mir/transform/simplify_comparison_integral.rs +++ b/compiler/rustc_mir/src/transform/simplify_comparison_integral.rs diff --git a/src/librustc_mir/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs index 06829cc2f14..06829cc2f14 100644 --- a/src/librustc_mir/transform/simplify_try.rs +++ b/compiler/rustc_mir/src/transform/simplify_try.rs diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs index 4cca4d223c0..4cca4d223c0 100644 --- a/src/librustc_mir/transform/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir/src/transform/uninhabited_enum_branching.rs diff --git a/src/librustc_mir/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs index fa362c66fb2..fa362c66fb2 100644 --- a/src/librustc_mir/transform/unreachable_prop.rs +++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs diff --git a/src/librustc_mir/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs index d7c9ecd0655..d7c9ecd0655 100644 --- a/src/librustc_mir/transform/validate.rs +++ b/compiler/rustc_mir/src/transform/validate.rs diff --git a/src/librustc_mir/util/aggregate.rs b/compiler/rustc_mir/src/util/aggregate.rs index 130409b9df5..130409b9df5 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/compiler/rustc_mir/src/util/aggregate.rs diff --git a/src/librustc_mir/util/alignment.rs b/compiler/rustc_mir/src/util/alignment.rs index 202e5e27f1d..202e5e27f1d 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/compiler/rustc_mir/src/util/alignment.rs diff --git a/src/librustc_mir/util/borrowck_errors.rs b/compiler/rustc_mir/src/util/borrowck_errors.rs index f8bb7e7a85d..f8bb7e7a85d 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/compiler/rustc_mir/src/util/borrowck_errors.rs diff --git a/src/librustc_mir/util/collect_writes.rs b/compiler/rustc_mir/src/util/collect_writes.rs index ecf3b08a96e..ecf3b08a96e 100644 --- a/src/librustc_mir/util/collect_writes.rs +++ b/compiler/rustc_mir/src/util/collect_writes.rs diff --git a/src/librustc_mir/util/def_use.rs b/compiler/rustc_mir/src/util/def_use.rs index b4448ead8eb..b4448ead8eb 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/compiler/rustc_mir/src/util/def_use.rs diff --git a/src/librustc_mir/util/elaborate_drops.rs b/compiler/rustc_mir/src/util/elaborate_drops.rs index 642935d243d..642935d243d 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/compiler/rustc_mir/src/util/elaborate_drops.rs diff --git a/src/librustc_mir/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs index 50193c4a0db..50193c4a0db 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/compiler/rustc_mir/src/util/graphviz.rs diff --git a/src/librustc_mir/util/mod.rs b/compiler/rustc_mir/src/util/mod.rs index 8bbe207c077..ed0fafb1aac 100644 --- a/src/librustc_mir/util/mod.rs +++ b/compiler/rustc_mir/src/util/mod.rs @@ -9,6 +9,7 @@ mod alignment; pub mod collect_writes; mod graphviz; pub(crate) mod pretty; +pub(crate) mod spanview; pub use self::aggregate::expand_aggregate; pub use self::alignment::is_disaligned; diff --git a/src/librustc_mir/util/patch.rs b/compiler/rustc_mir/src/util/patch.rs index 6566a996fe4..6566a996fe4 100644 --- a/src/librustc_mir/util/patch.rs +++ b/compiler/rustc_mir/src/util/patch.rs diff --git a/src/librustc_mir/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs index 2a9cbc7fc0e..db57766620e 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/compiler/rustc_mir/src/util/pretty.rs @@ -6,6 +6,7 @@ use std::io::{self, Write}; use std::path::{Path, PathBuf}; use super::graphviz::write_mir_fn_graphviz; +use super::spanview::write_mir_fn_spanview; use crate::transform::MirSource; use either::Either; use rustc_data_structures::fx::FxHashMap; @@ -147,6 +148,16 @@ fn dump_matched_mir_node<'tcx, F>( write_mir_fn_graphviz(tcx, source.def_id(), body, false, &mut file)?; }; } + + if let Some(spanview) = tcx.sess.opts.debugging_opts.dump_mir_spanview { + let _: io::Result<()> = try { + let mut file = + create_dump_file(tcx, "html", pass_num, pass_name, disambiguator, source)?; + if source.def_id().is_local() { + write_mir_fn_spanview(tcx, source.def_id(), body, spanview, &mut file)?; + } + }; + } } /// Returns the path to the filename where we should dump a given MIR. diff --git a/compiler/rustc_mir/src/util/spanview.rs b/compiler/rustc_mir/src/util/spanview.rs new file mode 100644 index 00000000000..b2f2b5fc1e6 --- /dev/null +++ b/compiler/rustc_mir/src/util/spanview.rs @@ -0,0 +1,461 @@ +use rustc_hir::def_id::DefId; +use rustc_middle::hir; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; +use rustc_session::config::MirSpanview; +use rustc_span::{BytePos, Pos, Span}; + +use std::io::{self, Write}; +use std::iter::Peekable; + +pub const TOOLTIP_INDENT: &str = " "; + +const NEW_LINE_SPAN: &str = "</span>\n<span class=\"line\">"; +const HEADER: &str = r#"<!DOCTYPE html> +<html> +<head> + <title>coverage_of_if_else - Code Regions</title> + <style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } + </style> +</head> +<body>"#; + +const FOOTER: &str = r#" +</body> +</html>"#; + +/// Metadata to highlight the span of a MIR BasicBlock, Statement, or Terminator. +pub struct SpanViewable { + pub span: Span, + pub title: String, + pub tooltip: String, +} + +/// Write a spanview HTML+CSS file to analyze MIR element spans. +pub fn write_mir_fn_spanview<'tcx, W>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + body: &Body<'tcx>, + spanview: MirSpanview, + w: &mut W, +) -> io::Result<()> +where + W: Write, +{ + let body_span = hir_body(tcx, def_id).value.span; + let mut span_viewables = Vec::new(); + for (bb, data) in body.basic_blocks().iter_enumerated() { + match spanview { + MirSpanview::Statement => { + for (i, statement) in data.statements.iter().enumerate() { + if let Some(span_viewable) = + statement_span_viewable(tcx, body_span, bb, i, statement) + { + span_viewables.push(span_viewable); + } + } + if let Some(span_viewable) = terminator_span_viewable(tcx, body_span, bb, data) { + span_viewables.push(span_viewable); + } + } + MirSpanview::Terminator => { + if let Some(span_viewable) = terminator_span_viewable(tcx, body_span, bb, data) { + span_viewables.push(span_viewable); + } + } + MirSpanview::Block => { + if let Some(span_viewable) = block_span_viewable(tcx, body_span, bb, data) { + span_viewables.push(span_viewable); + } + } + } + } + write_spanview_document(tcx, def_id, span_viewables, w)?; + Ok(()) +} + +/// Generate a spanview HTML+CSS document for the given local function `def_id`, and a pre-generated +/// list `SpanViewable`s. +pub fn write_spanview_document<'tcx, W>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + mut span_viewables: Vec<SpanViewable>, + w: &mut W, +) -> io::Result<()> +where + W: Write, +{ + let fn_span = fn_span(tcx, def_id); + writeln!(w, "{}", HEADER)?; + let mut next_pos = fn_span.lo(); + let end_pos = fn_span.hi(); + let source_map = tcx.sess.source_map(); + let start = source_map.lookup_char_pos(next_pos); + write!( + w, + r#"<div class="code" style="counter-reset: line {}"><span class="line">{}"#, + start.line - 1, + " ".repeat(start.col.to_usize()) + )?; + span_viewables.sort_unstable_by(|a, b| { + let a = a.span; + let b = b.span; + if a.lo() == b.lo() { + // Sort hi() in reverse order so shorter spans are attempted after longer spans. + // This should give shorter spans a higher "layer", so they are not covered by + // the longer spans. + b.hi().partial_cmp(&a.hi()) + } else { + a.lo().partial_cmp(&b.lo()) + } + .unwrap() + }); + let mut ordered_span_viewables = span_viewables.iter().peekable(); + let mut alt = false; + while ordered_span_viewables.peek().is_some() { + next_pos = write_span_viewables(tcx, next_pos, &mut ordered_span_viewables, false, 1, w)?; + alt = !alt; + } + if next_pos < end_pos { + write_coverage_gap(tcx, next_pos, end_pos, w)?; + } + write!(w, r#"</span></div>"#)?; + writeln!(w, "{}", FOOTER)?; + Ok(()) +} + +/// Format a string showing the start line and column, and end line and column within a file. +pub fn source_range_no_file<'tcx>(tcx: TyCtxt<'tcx>, span: &Span) -> String { + let source_map = tcx.sess.source_map(); + let start = source_map.lookup_char_pos(span.lo()); + let end = source_map.lookup_char_pos(span.hi()); + format!("{}:{}-{}:{}", start.line, start.col.to_usize() + 1, end.line, end.col.to_usize() + 1) +} + +pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str { + use StatementKind::*; + match statement.kind { + Assign(..) => "Assign", + FakeRead(..) => "FakeRead", + SetDiscriminant { .. } => "SetDiscriminant", + StorageLive(..) => "StorageLive", + StorageDead(..) => "StorageDead", + LlvmInlineAsm(..) => "LlvmInlineAsm", + Retag(..) => "Retag", + AscribeUserType(..) => "AscribeUserType", + Coverage(..) => "Coverage", + Nop => "Nop", + } +} + +pub fn terminator_kind_name(term: &Terminator<'_>) -> &'static str { + use TerminatorKind::*; + match term.kind { + Goto { .. } => "Goto", + SwitchInt { .. } => "SwitchInt", + Resume => "Resume", + Abort => "Abort", + Return => "Return", + Unreachable => "Unreachable", + Drop { .. } => "Drop", + DropAndReplace { .. } => "DropAndReplace", + Call { .. } => "Call", + Assert { .. } => "Assert", + Yield { .. } => "Yield", + GeneratorDrop => "GeneratorDrop", + FalseEdge { .. } => "FalseEdge", + FalseUnwind { .. } => "FalseUnwind", + InlineAsm { .. } => "InlineAsm", + } +} + +fn statement_span_viewable<'tcx>( + tcx: TyCtxt<'tcx>, + body_span: Span, + bb: BasicBlock, + i: usize, + statement: &Statement<'tcx>, +) -> Option<SpanViewable> { + let span = statement.source_info.span; + if !body_span.contains(span) { + return None; + } + let title = format!("bb{}[{}]", bb.index(), i); + let tooltip = tooltip(tcx, &title, span, vec![statement.clone()], &None); + Some(SpanViewable { span, title, tooltip }) +} + +fn terminator_span_viewable<'tcx>( + tcx: TyCtxt<'tcx>, + body_span: Span, + bb: BasicBlock, + data: &BasicBlockData<'tcx>, +) -> Option<SpanViewable> { + let term = data.terminator(); + let span = term.source_info.span; + if !body_span.contains(span) { + return None; + } + let title = format!("bb{}`{}`", bb.index(), terminator_kind_name(term)); + let tooltip = tooltip(tcx, &title, span, vec![], &data.terminator); + Some(SpanViewable { span, title, tooltip }) +} + +fn block_span_viewable<'tcx>( + tcx: TyCtxt<'tcx>, + body_span: Span, + bb: BasicBlock, + data: &BasicBlockData<'tcx>, +) -> Option<SpanViewable> { + let span = compute_block_span(data, body_span); + if !body_span.contains(span) { + return None; + } + let title = format!("bb{}", bb.index()); + let tooltip = tooltip(tcx, &title, span, data.statements.clone(), &data.terminator); + Some(SpanViewable { span, title, tooltip }) +} + +fn compute_block_span<'tcx>(data: &BasicBlockData<'tcx>, body_span: Span) -> Span { + let mut span = data.terminator().source_info.span; + for statement_span in data.statements.iter().map(|statement| statement.source_info.span) { + // Only combine Spans from the function's body_span. + if body_span.contains(statement_span) { + span = span.to(statement_span); + } + } + span +} + +/// Recursively process each ordered span. Spans that overlap will have progressively varying +/// styles, such as increased padding for each overlap. Non-overlapping adjacent spans will +/// have alternating style choices, to help distinguish between them if, visually adjacent. +/// The `layer` is incremented for each overlap, and the `alt` bool alternates between true +/// and false, for each adjacent non-overlapping span. Source code between the spans (code +/// that is not in any coverage region) has neutral styling. +fn write_span_viewables<'tcx, 'b, W>( + tcx: TyCtxt<'tcx>, + next_pos: BytePos, + ordered_span_viewables: &mut Peekable<impl Iterator<Item = &'b SpanViewable>>, + alt: bool, + layer: usize, + w: &mut W, +) -> io::Result<BytePos> +where + W: Write, +{ + let span_viewable = + ordered_span_viewables.next().expect("ordered_span_viewables should have some"); + if next_pos < span_viewable.span.lo() { + write_coverage_gap(tcx, next_pos, span_viewable.span.lo(), w)?; + } + let mut remaining_span = span_viewable.span; + let mut subalt = false; + loop { + let next_span_viewable = match ordered_span_viewables.peek() { + None => break, + Some(span_viewable) => *span_viewable, + }; + if !next_span_viewable.span.overlaps(remaining_span) { + break; + } + write_span( + tcx, + remaining_span.until(next_span_viewable.span), + Some(span_viewable), + alt, + layer, + w, + )?; + let next_pos = write_span_viewables( + tcx, + next_span_viewable.span.lo(), + ordered_span_viewables, + subalt, + layer + 1, + w, + )?; + subalt = !subalt; + if next_pos < remaining_span.hi() { + remaining_span = remaining_span.with_lo(next_pos); + } else { + return Ok(next_pos); + } + } + write_span(tcx, remaining_span, Some(span_viewable), alt, layer, w) +} + +fn write_coverage_gap<'tcx, W>( + tcx: TyCtxt<'tcx>, + lo: BytePos, + hi: BytePos, + w: &mut W, +) -> io::Result<BytePos> +where + W: Write, +{ + write_span(tcx, Span::with_root_ctxt(lo, hi), None, false, 0, w) +} + +fn write_span<'tcx, W>( + tcx: TyCtxt<'tcx>, + span: Span, + span_viewable: Option<&SpanViewable>, + alt: bool, + layer: usize, + w: &mut W, +) -> io::Result<BytePos> +where + W: Write, +{ + let source_map = tcx.sess.source_map(); + let snippet = source_map + .span_to_snippet(span) + .unwrap_or_else(|err| bug!("span_to_snippet error for span {:?}: {:?}", span, err)); + let labeled_snippet = if let Some(SpanViewable { title, .. }) = span_viewable { + if span.is_empty() { + format!(r#"<span class="annotation">@{}</span>"#, title) + } else { + format!(r#"<span class="annotation">@{}:</span> {}"#, title, escape_html(&snippet)) + } + } else { + snippet + }; + let maybe_alt = if layer > 0 { + if alt { " odd" } else { " even" } + } else { + "" + }; + let maybe_tooltip = if let Some(SpanViewable { tooltip, .. }) = span_viewable { + format!(" title=\"{}\"", escape_attr(tooltip)) + } else { + "".to_owned() + }; + if layer == 1 { + write!(w, "<span>")?; + } + for (i, line) in labeled_snippet.lines().enumerate() { + if i > 0 { + write!(w, "{}", NEW_LINE_SPAN)?; + } + write!( + w, + r#"<span class="code{}" style="--layer: {}"{}>{}</span>"#, + maybe_alt, layer, maybe_tooltip, line + )?; + } + if layer == 1 { + write!(w, "</span>")?; + } + Ok(span.hi()) +} + +fn tooltip<'tcx>( + tcx: TyCtxt<'tcx>, + title: &str, + span: Span, + statements: Vec<Statement<'tcx>>, + terminator: &Option<Terminator<'tcx>>, +) -> String { + let source_map = tcx.sess.source_map(); + let mut text = Vec::new(); + text.push(format!("{}: {}:", title, &source_map.span_to_string(span))); + for statement in statements { + let source_range = source_range_no_file(tcx, &statement.source_info.span); + text.push(format!( + "\n{}{}: {}: {}", + TOOLTIP_INDENT, + source_range, + statement_kind_name(&statement), + format!("{:?}", statement) + )); + } + if let Some(term) = terminator { + let source_range = source_range_no_file(tcx, &term.source_info.span); + text.push(format!( + "\n{}{}: {}: {:?}", + TOOLTIP_INDENT, + source_range, + terminator_kind_name(term), + term.kind + )); + } + text.join("") +} + +fn fn_span<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Span { + let hir_id = + tcx.hir().local_def_id_to_hir_id(def_id.as_local().expect("expected DefId is local")); + tcx.hir().span(hir_id) +} + +fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx rustc_hir::Body<'tcx> { + let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local"); + let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body"); + tcx.hir().body(fn_body_id) +} + +fn escape_html(s: &str) -> String { + s.replace("&", "&").replace("<", "<").replace(">", ">") +} + +fn escape_attr(s: &str) -> String { + s.replace("&", "&") + .replace("\"", """) + .replace("'", "'") + .replace("<", "<") + .replace(">", ">") +} diff --git a/src/librustc_mir/util/storage.rs b/compiler/rustc_mir/src/util/storage.rs index 0b7b1c29537..0b7b1c29537 100644 --- a/src/librustc_mir/util/storage.rs +++ b/compiler/rustc_mir/src/util/storage.rs diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml new file mode 100644 index 00000000000..2dd894a67a6 --- /dev/null +++ b/compiler/rustc_mir_build/Cargo.toml @@ -0,0 +1,27 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_mir_build" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_arena = { path = "../rustc_arena" } +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_apfloat = { path = "../rustc_apfloat" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_infer = { path = "../rustc_infer" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } +rustc_trait_selection = { path = "../rustc_trait_selection" } +rustc_ast = { path = "../rustc_ast" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_mir_build/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index d1cbf209b06..d1cbf209b06 100644 --- a/src/librustc_mir_build/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs diff --git a/src/librustc_mir_build/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index 42e2b242d77..42e2b242d77 100644 --- a/src/librustc_mir_build/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs diff --git a/src/librustc_mir_build/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 982aefcf604..982aefcf604 100644 --- a/src/librustc_mir_build/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs diff --git a/src/librustc_mir_build/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index aac93f313f4..aac93f313f4 100644 --- a/src/librustc_mir_build/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs diff --git a/src/librustc_mir_build/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 1e3e104c2ba..1e3e104c2ba 100644 --- a/src/librustc_mir_build/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 9c5fddc6b77..9c5fddc6b77 100644 --- a/src/librustc_mir_build/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs index a9cc0cc2f24..a9cc0cc2f24 100644 --- a/src/librustc_mir_build/build/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs diff --git a/src/librustc_mir_build/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs index 9cabd186d84..9cabd186d84 100644 --- a/src/librustc_mir_build/build/expr/category.rs +++ b/compiler/rustc_mir_build/src/build/expr/category.rs diff --git a/src/librustc_mir_build/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 3d623abfa6e..3d623abfa6e 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs diff --git a/src/librustc_mir_build/build/expr/mod.rs b/compiler/rustc_mir_build/src/build/expr/mod.rs index ac8c7e725e1..ac8c7e725e1 100644 --- a/src/librustc_mir_build/build/expr/mod.rs +++ b/compiler/rustc_mir_build/src/build/expr/mod.rs diff --git a/src/librustc_mir_build/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index f117689d940..f117689d940 100644 --- a/src/librustc_mir_build/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs diff --git a/src/librustc_mir_build/build/into.rs b/compiler/rustc_mir_build/src/build/into.rs index 7264e495b84..7264e495b84 100644 --- a/src/librustc_mir_build/build/into.rs +++ b/compiler/rustc_mir_build/src/build/into.rs diff --git a/src/librustc_mir_build/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3a525d10b08..3a525d10b08 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index e584aeb9226..e584aeb9226 100644 --- a/src/librustc_mir_build/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs diff --git a/src/librustc_mir_build/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index c4a87a554a3..c4a87a554a3 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs diff --git a/src/librustc_mir_build/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index c6d39947f7d..c6d39947f7d 100644 --- a/src/librustc_mir_build/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs diff --git a/src/librustc_mir_build/build/misc.rs b/compiler/rustc_mir_build/src/build/misc.rs index 29651d9bc66..29651d9bc66 100644 --- a/src/librustc_mir_build/build/misc.rs +++ b/compiler/rustc_mir_build/src/build/misc.rs diff --git a/src/librustc_mir_build/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 249cce0ba19..249cce0ba19 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs diff --git a/src/librustc_mir_build/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 2a03bb78c6b..2a03bb78c6b 100644 --- a/src/librustc_mir_build/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs diff --git a/src/librustc_mir_build/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 313bb979a51..313bb979a51 100644 --- a/src/librustc_mir_build/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs diff --git a/src/librustc_mir_build/lints.rs b/compiler/rustc_mir_build/src/lints.rs index fd2d5a4abd4..fd2d5a4abd4 100644 --- a/src/librustc_mir_build/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs diff --git a/src/librustc_mir_build/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index dd5515d39b0..dd5515d39b0 100644 --- a/src/librustc_mir_build/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs diff --git a/src/librustc_mir_build/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 980888df7fe..980888df7fe 100644 --- a/src/librustc_mir_build/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs diff --git a/src/librustc_mir_build/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 066e46fec14..066e46fec14 100644 --- a/src/librustc_mir_build/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs diff --git a/src/librustc_mir_build/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index cf42fee873e..cf42fee873e 100644 --- a/src/librustc_mir_build/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs diff --git a/src/librustc_mir_build/thir/cx/to_ref.rs b/compiler/rustc_mir_build/src/thir/cx/to_ref.rs index 53a988ebb79..53a988ebb79 100644 --- a/src/librustc_mir_build/thir/cx/to_ref.rs +++ b/compiler/rustc_mir_build/src/thir/cx/to_ref.rs diff --git a/src/librustc_mir_build/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs index 2837bfa040f..2837bfa040f 100644 --- a/src/librustc_mir_build/thir/mod.rs +++ b/compiler/rustc_mir_build/src/thir/mod.rs diff --git a/src/librustc_mir_build/thir/pattern/_match.rs b/compiler/rustc_mir_build/src/thir/pattern/_match.rs index 3202f7d1b1b..3202f7d1b1b 100644 --- a/src/librustc_mir_build/thir/pattern/_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/_match.rs diff --git a/src/librustc_mir_build/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 4e7108667e1..4e7108667e1 100644 --- a/src/librustc_mir_build/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs diff --git a/src/librustc_mir_build/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index f6d3ccc1ae0..f6d3ccc1ae0 100644 --- a/src/librustc_mir_build/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs diff --git a/src/librustc_mir_build/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index c163cb0e60c..c163cb0e60c 100644 --- a/src/librustc_mir_build/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs diff --git a/src/librustc_mir_build/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 7de60ddda41..7de60ddda41 100644 --- a/src/librustc_mir_build/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml new file mode 100644 index 00000000000..52835e5c8a9 --- /dev/null +++ b/compiler/rustc_parse/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_parse" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +bitflags = "1.0" +tracing = "0.1" +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_feature = { path = "../rustc_feature" } +rustc_lexer = { path = "../rustc_lexer" } +rustc_errors = { path = "../rustc_errors" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rustc_ast = { path = "../rustc_ast" } +unicode-normalization = "0.1.11" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_parse/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index a65d3446819..034442b798b 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -1,5 +1,6 @@ use rustc_ast::ast::AttrStyle; use rustc_ast::token::{self, CommentKind, Token, TokenKind}; +use rustc_ast::tokenstream::IsJoint; use rustc_data_structures::sync::Lrc; use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError}; use rustc_lexer::Base; @@ -27,7 +28,7 @@ pub struct UnmatchedBrace { pub candidate_span: Option<Span>, } -pub struct StringReader<'a> { +crate struct StringReader<'a> { sess: &'a ParseSess, /// Initial position, read-only. start_pos: BytePos, @@ -41,7 +42,7 @@ pub struct StringReader<'a> { } impl<'a> StringReader<'a> { - pub fn new( + crate fn new( sess: &'a ParseSess, source_file: Lrc<rustc_span::SourceFile>, override_span: Option<Span>, @@ -65,42 +66,46 @@ impl<'a> StringReader<'a> { self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi)) } - /// Returns the next token, including trivia like whitespace or comments. - pub fn next_token(&mut self) -> Token { + /// Returns the next token, and info about preceding whitespace, if any. + fn next_token(&mut self) -> (IsJoint, Token) { + let mut is_joint = IsJoint::Joint; + + // Skip `#!` at the start of the file let start_src_index = self.src_index(self.pos); let text: &str = &self.src[start_src_index..self.end_src_index]; - - if text.is_empty() { - let span = self.mk_sp(self.pos, self.pos); - return Token::new(token::Eof, span); + let is_beginning_of_file = self.pos == self.start_pos; + if is_beginning_of_file { + if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { + self.pos = self.pos + BytePos::from_usize(shebang_len); + is_joint = IsJoint::NonJoint; + } } - { - let is_beginning_of_file = self.pos == self.start_pos; - if is_beginning_of_file { - if let Some(shebang_len) = rustc_lexer::strip_shebang(text) { - let start = self.pos; - self.pos = self.pos + BytePos::from_usize(shebang_len); + // Skip trivial (whitespace & comments) tokens + loop { + let start_src_index = self.src_index(self.pos); + let text: &str = &self.src[start_src_index..self.end_src_index]; - let sym = self.symbol_from(start + BytePos::from_usize("#!".len())); - let kind = token::Shebang(sym); - - let span = self.mk_sp(start, self.pos); - return Token::new(kind, span); - } + if text.is_empty() { + let span = self.mk_sp(self.pos, self.pos); + return (is_joint, Token::new(token::Eof, span)); } - } - let token = rustc_lexer::first_token(text); + let token = rustc_lexer::first_token(text); - let start = self.pos; - self.pos = self.pos + BytePos::from_usize(token.len); + let start = self.pos; + self.pos = self.pos + BytePos::from_usize(token.len); - debug!("try_next_token: {:?}({:?})", token.kind, self.str_from(start)); + debug!("next_token: {:?}({:?})", token.kind, self.str_from(start)); - let kind = self.cook_lexer_token(token.kind, start); - let span = self.mk_sp(start, self.pos); - Token::new(kind, span) + match self.cook_lexer_token(token.kind, start) { + Some(kind) => { + let span = self.mk_sp(start, self.pos); + return (is_joint, Token::new(kind, span)); + } + None => is_joint = IsJoint::NonJoint, + } + } } /// Report a fatal lexical error with a given span. @@ -140,19 +145,16 @@ impl<'a> StringReader<'a> { /// Turns simple `rustc_lexer::TokenKind` enum into a rich /// `librustc_ast::TokenKind`. This turns strings into interned /// symbols and runs additional validation. - fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> TokenKind { - match token { + fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> Option<TokenKind> { + Some(match token { rustc_lexer::TokenKind::LineComment { doc_style } => { - match doc_style { - Some(doc_style) => { - // Opening delimiter of the length 3 is not included into the symbol. - let content_start = start + BytePos(3); - let content = self.str_from(content_start); + // Skip non-doc comments + let doc_style = doc_style?; - self.cook_doc_comment(content_start, content, CommentKind::Line, doc_style) - } - None => token::Comment, - } + // Opening delimiter of the length 3 is not included into the symbol. + let content_start = start + BytePos(3); + let content = self.str_from(content_start); + self.cook_doc_comment(content_start, content, CommentKind::Line, doc_style) } rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => { if !terminated { @@ -171,20 +173,18 @@ impl<'a> StringReader<'a> { .emit(); FatalError.raise(); } - match doc_style { - Some(doc_style) => { - // Opening delimiter of the length 3 and closing delimiter of the length 2 - // are not included into the symbol. - let content_start = start + BytePos(3); - let content_end = self.pos - BytePos(if terminated { 2 } else { 0 }); - let content = self.str_from_to(content_start, content_end); - - self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style) - } - None => token::Comment, - } + + // Skip non-doc comments + let doc_style = doc_style?; + + // Opening delimiter of the length 3 and closing delimiter of the length 2 + // are not included into the symbol. + let content_start = start + BytePos(3); + let content_end = self.pos - BytePos(if terminated { 2 } else { 0 }); + let content = self.str_from_to(content_start, content_end); + self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style) } - rustc_lexer::TokenKind::Whitespace => token::Whitespace, + rustc_lexer::TokenKind::Whitespace => return None, rustc_lexer::TokenKind::Ident | rustc_lexer::TokenKind::RawIdent => { let is_raw_ident = token == rustc_lexer::TokenKind::RawIdent; let mut ident_start = start; @@ -282,12 +282,11 @@ impl<'a> StringReader<'a> { // this should be inside `rustc_lexer`. However, we should first remove compound // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it, // as there will be less overall work to do this way. - let token = unicode_chars::check_for_substitution(self, start, c, &mut err) - .unwrap_or_else(|| token::Unknown(self.symbol_from(start))); + let token = unicode_chars::check_for_substitution(self, start, c, &mut err); err.emit(); - token + token? } - } + }) } fn cook_doc_comment( @@ -439,10 +438,6 @@ impl<'a> StringReader<'a> { (lit_kind, id) } - pub fn pos(&self) -> BytePos { - self.pos - } - #[inline] fn src_index(&self, pos: BytePos) -> usize { (pos - self.start_pos).to_usize() @@ -454,12 +449,6 @@ impl<'a> StringReader<'a> { self.str_from_to(start, self.pos) } - /// Creates a Symbol from a given offset to the current offset. - fn symbol_from(&self, start: BytePos) -> Symbol { - debug!("taking an ident from {:?} to {:?}", start, self.pos); - Symbol::intern(self.str_from(start)) - } - /// As symbol_from, with an explicit endpoint. fn symbol_from_to(&self, start: BytePos, end: BytePos) -> Symbol { debug!("taking an ident from {:?} to {:?}", start, end); diff --git a/src/librustc_parse/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index c08659ec9f6..d5977ca3c7d 100644 --- a/src/librustc_parse/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -16,7 +16,6 @@ impl<'a> StringReader<'a> { let mut tt_reader = TokenTreesReader { string_reader: self, token: Token::dummy(), - joint_to_prev: Joint, open_braces: Vec::new(), unmatched_braces: Vec::new(), matching_delim_spans: Vec::new(), @@ -32,7 +31,6 @@ impl<'a> StringReader<'a> { struct TokenTreesReader<'a> { string_reader: StringReader<'a>, token: Token, - joint_to_prev: IsJoint, /// Stack of open delimiters and their spans. Used for error message. open_braces: Vec<(token::DelimToken, Span)>, unmatched_braces: Vec<UnmatchedBrace>, @@ -53,7 +51,7 @@ impl<'a> TokenTreesReader<'a> { fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> { let mut buf = TokenStreamBuilder::default(); - self.real_token(); + self.bump(); while self.token != token::Eof { buf.push(self.parse_token_tree()?); } @@ -126,7 +124,7 @@ impl<'a> TokenTreesReader<'a> { // Parse the open delimiter. self.open_braces.push((delim, self.token.span)); - self.real_token(); + self.bump(); // Parse the token trees within the delimiters. // We stop at any delimiter so we can try to recover if the user @@ -171,7 +169,7 @@ impl<'a> TokenTreesReader<'a> { )); } // Parse the closing delimiter. - self.real_token(); + self.bump(); } // Incorrect delimiter. token::CloseDelim(other) => { @@ -217,7 +215,7 @@ impl<'a> TokenTreesReader<'a> { // bar(baz( // } // Incorrect delimiter but matches the earlier `{` if !self.open_braces.iter().any(|&(b, _)| b == other) { - self.real_token(); + self.bump(); } } token::Eof => { @@ -264,27 +262,19 @@ impl<'a> TokenTreesReader<'a> { } _ => { let tt = TokenTree::Token(self.token.take()); - self.real_token(); - let is_joint = self.joint_to_prev == Joint && self.token.is_op(); - Ok((tt, if is_joint { Joint } else { NonJoint })) + let mut is_joint = self.bump(); + if !self.token.is_op() { + is_joint = NonJoint; + } + Ok((tt, is_joint)) } } } - fn real_token(&mut self) { - self.joint_to_prev = Joint; - loop { - let token = self.string_reader.next_token(); - match token.kind { - token::Whitespace | token::Comment | token::Shebang(_) | token::Unknown(_) => { - self.joint_to_prev = NonJoint; - } - _ => { - self.token = token; - return; - } - } - } + fn bump(&mut self) -> IsJoint { + let (joint_to_prev, token) = self.string_reader.next_token(); + self.token = token; + joint_to_prev } } diff --git a/src/librustc_parse/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 6f249f491a6..6f249f491a6 100644 --- a/src/librustc_parse/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs diff --git a/src/librustc_parse/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index ac395f6cbc2..8dc0db01ecb 100644 --- a/src/librustc_parse/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -303,7 +303,7 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ // However, we should first remove compound tokens like `<<` from `rustc_lexer`, and then add // fancier error recovery to it, as there will be less overall work to do this way. const ASCII_ARRAY: &[(char, &str, Option<token::TokenKind>)] = &[ - (' ', "Space", Some(token::Whitespace)), + (' ', "Space", None), ('_', "Underscore", Some(token::Ident(kw::Underscore, false))), ('-', "Minus/Hyphen", Some(token::BinOp(token::Minus))), (',', "Comma", Some(token::Comma)), diff --git a/src/librustc_parse/lib.rs b/compiler/rustc_parse/src/lib.rs index bc857c97742..462279b0a9e 100644 --- a/src/librustc_parse/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -348,9 +348,6 @@ pub fn tokenstream_probably_equal_for_proc_macro( | token::CloseDelim(DelimToken::NoDelim) // The pretty printer collapses many semicolons into one. | token::Semi - // The pretty printer collapses whitespace arbitrarily and can - // introduce whitespace from `NoDelim`. - | token::Whitespace // The pretty printer can turn `$crate` into `::crate_name` | token::ModSep = token.kind { return false; @@ -506,8 +503,6 @@ fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool { | (&Pound, &Pound) | (&Dollar, &Dollar) | (&Question, &Question) - | (&Whitespace, &Whitespace) - | (&Comment, &Comment) | (&Eof, &Eof) => true, (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b, @@ -516,8 +511,6 @@ fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool { (&DocComment(a1, a2, a3), &DocComment(b1, b2, b3)) => a1 == b1 && a2 == b2 && a3 == b3, - (&Shebang(a), &Shebang(b)) => a == b, - (&Literal(a), &Literal(b)) => a == b, (&Lifetime(a), &Lifetime(b)) => a == b, diff --git a/src/librustc_parse/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 4e4429e461f..4e4429e461f 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs diff --git a/src/librustc_parse/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 12efe391fb9..12efe391fb9 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs diff --git a/src/librustc_parse/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index f022c628fe2..69d13b5cf53 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1480,7 +1480,7 @@ impl<'a> Parser<'a> { /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`). /// Keep this in sync with `Token::can_begin_literal_maybe_minus`. - pub(super) fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { + pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { maybe_whole_expr!(self); let lo = self.token.span; diff --git a/src/librustc_parse/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index dd99a7587dd..dd99a7587dd 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs diff --git a/src/librustc_parse/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 9143af651df..9143af651df 100644 --- a/src/librustc_parse/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs diff --git a/src/librustc_parse/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index d67ed74bc99..84edfecad19 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1014,7 +1014,8 @@ impl<'a> Parser<'a> { /// If the following element can't be a tuple (i.e., it's a function definition), then /// it's not a tuple struct field), and the contents within the parentheses isn't valid, /// so emit a proper diagnostic. - pub(crate) fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { + // Public for rustfmt usage. + pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { maybe_whole!(self, NtVis, |x| x); self.expected_tokens.push(TokenType::Keyword(kw::Crate)); @@ -1233,6 +1234,10 @@ impl<'a> Parser<'a> { *t == token::OpenDelim(token::Brace) || *t == token::BinOp(token::Star) }) } + + pub fn clear_expected_tokens(&mut self) { + self.expected_tokens.clear(); + } } crate fn make_unclosed_delims_error( diff --git a/src/librustc_parse/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index f40cd1131d2..f40cd1131d2 100644 --- a/src/librustc_parse/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs diff --git a/src/librustc_parse/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 2c0133a24dc..2c0133a24dc 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs diff --git a/src/librustc_parse/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 54b4df8613f..54b4df8613f 100644 --- a/src/librustc_parse/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs diff --git a/src/librustc_parse/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index ac067cb0eab..947ca6b5bd5 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -10,7 +10,7 @@ use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, TokenKind}; use rustc_ast::util::classify; -use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacStmtStyle}; +use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle}; use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID}; use rustc_errors::{Applicability, PResult}; use rustc_span::source_map::{BytePos, Span}; @@ -21,7 +21,8 @@ use std::mem; impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. - pub(super) fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> { + // Public for rustfmt usage. + pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> { Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| { e.emit(); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); @@ -106,7 +107,7 @@ impl<'a> Parser<'a> { let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof { - StmtKind::MacCall(P((mac, style, attrs))) + StmtKind::MacCall(P(MacCallStmt { mac, style, attrs })) } else { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new()); diff --git a/src/librustc_parse/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 4356850818e..4356850818e 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs diff --git a/src/librustc_parse/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index f4bb9610940..f4bb9610940 100644 --- a/src/librustc_parse/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml new file mode 100644 index 00000000000..c2317d91a6e --- /dev/null +++ b/compiler/rustc_parse_format/Cargo.toml @@ -0,0 +1,9 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_parse_format" +version = "0.0.0" +edition = "2018" + +[dependencies] +rustc_span = { path = "../rustc_span" } +rustc_lexer = { path = "../rustc_lexer" } diff --git a/src/librustc_parse_format/lib.rs b/compiler/rustc_parse_format/src/lib.rs index e07b8b86aef..e07b8b86aef 100644 --- a/src/librustc_parse_format/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs diff --git a/src/librustc_parse_format/tests.rs b/compiler/rustc_parse_format/src/tests.rs index 9fd0497fffe..9fd0497fffe 100644 --- a/src/librustc_parse_format/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml new file mode 100644 index 00000000000..4c3a96eed04 --- /dev/null +++ b/compiler/rustc_passes/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_passes" +version = "0.0.0" +edition = "2018" + +[dependencies] +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_session = { path = "../rustc_session" } +rustc_target = { path = "../rustc_target" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/src/librustc_passes/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 832cde86d0b..832cde86d0b 100644 --- a/src/librustc_passes/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs diff --git a/src/librustc_passes/check_const.rs b/compiler/rustc_passes/src/check_const.rs index dd0bcbf208d..dd0bcbf208d 100644 --- a/src/librustc_passes/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs diff --git a/src/librustc_passes/dead.rs b/compiler/rustc_passes/src/dead.rs index 01da33ddd2e..01da33ddd2e 100644 --- a/src/librustc_passes/dead.rs +++ b/compiler/rustc_passes/src/dead.rs diff --git a/src/librustc_passes/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index df0f9f157ae..df0f9f157ae 100644 --- a/src/librustc_passes/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs diff --git a/src/librustc_passes/entry.rs b/compiler/rustc_passes/src/entry.rs index 8aa6e7936be..8aa6e7936be 100644 --- a/src/librustc_passes/entry.rs +++ b/compiler/rustc_passes/src/entry.rs diff --git a/src/librustc_passes/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 2edbc29b7ef..2edbc29b7ef 100644 --- a/src/librustc_passes/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs diff --git a/src/librustc_passes/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 9537321026e..9537321026e 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs diff --git a/src/librustc_passes/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index ebe231009d3..ebe231009d3 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs diff --git a/src/librustc_passes/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 0ae0c381a11..0ae0c381a11 100644 --- a/src/librustc_passes/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs diff --git a/src/librustc_passes/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 504cbbfcb76..504cbbfcb76 100644 --- a/src/librustc_passes/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs diff --git a/src/librustc_passes/lib.rs b/compiler/rustc_passes/src/lib.rs index be4c542ec3a..be4c542ec3a 100644 --- a/src/librustc_passes/lib.rs +++ b/compiler/rustc_passes/src/lib.rs diff --git a/src/librustc_passes/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 7c62a234dba..7c62a234dba 100644 --- a/src/librustc_passes/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs diff --git a/src/librustc_passes/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 55525586479..55525586479 100644 --- a/src/librustc_passes/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs diff --git a/src/librustc_passes/loops.rs b/compiler/rustc_passes/src/loops.rs index 9b4da71e5e9..9b4da71e5e9 100644 --- a/src/librustc_passes/loops.rs +++ b/compiler/rustc_passes/src/loops.rs diff --git a/src/librustc_passes/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 8d5c980609c..8d5c980609c 100644 --- a/src/librustc_passes/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs diff --git a/src/librustc_passes/region.rs b/compiler/rustc_passes/src/region.rs index 1af79abe4b9..1af79abe4b9 100644 --- a/src/librustc_passes/region.rs +++ b/compiler/rustc_passes/src/region.rs diff --git a/src/librustc_passes/stability.rs b/compiler/rustc_passes/src/stability.rs index 91edc7d9db7..91edc7d9db7 100644 --- a/src/librustc_passes/stability.rs +++ b/compiler/rustc_passes/src/stability.rs diff --git a/src/librustc_passes/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 91b8ae07637..91b8ae07637 100644 --- a/src/librustc_passes/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs diff --git a/src/librustc_passes/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 6bc2110bfb3..6bc2110bfb3 100644 --- a/src/librustc_passes/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs diff --git a/compiler/rustc_plugin_impl/Cargo.toml b/compiler/rustc_plugin_impl/Cargo.toml new file mode 100644 index 00000000000..500d13a8c16 --- /dev/null +++ b/compiler/rustc_plugin_impl/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_plugin_impl" +version = "0.0.0" +build = false +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_middle = { path = "../rustc_middle" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_lint = { path = "../rustc_lint" } +rustc_metadata = { path = "../rustc_metadata" } +rustc_ast = { path = "../rustc_ast" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } diff --git a/src/librustc_plugin_impl/build.rs b/compiler/rustc_plugin_impl/src/build.rs index d16dd701a12..d16dd701a12 100644 --- a/src/librustc_plugin_impl/build.rs +++ b/compiler/rustc_plugin_impl/src/build.rs diff --git a/src/librustc_plugin_impl/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs index 1eb65dd96ba..1eb65dd96ba 100644 --- a/src/librustc_plugin_impl/lib.rs +++ b/compiler/rustc_plugin_impl/src/lib.rs diff --git a/src/librustc_plugin_impl/load.rs b/compiler/rustc_plugin_impl/src/load.rs index 687f7db221f..687f7db221f 100644 --- a/src/librustc_plugin_impl/load.rs +++ b/compiler/rustc_plugin_impl/src/load.rs diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml new file mode 100644 index 00000000000..ce83dc1de78 --- /dev/null +++ b/compiler/rustc_privacy/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_privacy" +version = "0.0.0" +edition = "2018" + +[dependencies] +rustc_middle = { path = "../rustc_middle" } +rustc_attr = { path = "../rustc_attr" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_typeck = { path = "../rustc_typeck" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rustc_data_structures = { path = "../rustc_data_structures" } +tracing = "0.1" diff --git a/src/librustc_privacy/lib.rs b/compiler/rustc_privacy/src/lib.rs index deb4277cb38..deb4277cb38 100644 --- a/src/librustc_privacy/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml new file mode 100644 index 00000000000..7defb00a881 --- /dev/null +++ b/compiler/rustc_query_system/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_query_system" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_arena = { path = "../rustc_arena" } +tracing = "0.1" +rustc-rayon-core = "0.3.0" +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_macros = { path = "../rustc_macros" } +rustc_index = { path = "../rustc_index" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } +parking_lot = "0.10" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_query_system/cache.rs b/compiler/rustc_query_system/src/cache.rs index be3d3607728..be3d3607728 100644 --- a/src/librustc_query_system/cache.rs +++ b/compiler/rustc_query_system/src/cache.rs diff --git a/src/librustc_query_system/dep_graph/README.md b/compiler/rustc_query_system/src/dep_graph/README.md index b9d91cd35a8..b9d91cd35a8 100644 --- a/src/librustc_query_system/dep_graph/README.md +++ b/compiler/rustc_query_system/src/dep_graph/README.md diff --git a/src/librustc_query_system/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs index 718a2f1039a..718a2f1039a 100644 --- a/src/librustc_query_system/dep_graph/debug.rs +++ b/compiler/rustc_query_system/src/dep_graph/debug.rs diff --git a/src/librustc_query_system/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index e302784cc3e..e302784cc3e 100644 --- a/src/librustc_query_system/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs diff --git a/src/librustc_query_system/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index d70306b4869..d70306b4869 100644 --- a/src/librustc_query_system/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs diff --git a/src/librustc_query_system/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index e8d02692f37..e8d02692f37 100644 --- a/src/librustc_query_system/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs diff --git a/src/librustc_query_system/dep_graph/prev.rs b/compiler/rustc_query_system/src/dep_graph/prev.rs index 29357ce9449..29357ce9449 100644 --- a/src/librustc_query_system/dep_graph/prev.rs +++ b/compiler/rustc_query_system/src/dep_graph/prev.rs diff --git a/src/librustc_query_system/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index fb313d2658f..fb313d2658f 100644 --- a/src/librustc_query_system/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs diff --git a/src/librustc_query_system/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 932c6d2a2f1..932c6d2a2f1 100644 --- a/src/librustc_query_system/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs diff --git a/src/librustc_query_system/lib.rs b/compiler/rustc_query_system/src/lib.rs index 26b76a9c006..26b76a9c006 100644 --- a/src/librustc_query_system/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs diff --git a/src/librustc_query_system/query/README.md b/compiler/rustc_query_system/src/query/README.md index 8ec07b9fdeb..8ec07b9fdeb 100644 --- a/src/librustc_query_system/query/README.md +++ b/compiler/rustc_query_system/src/query/README.md diff --git a/src/librustc_query_system/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 1839e1af45e..1839e1af45e 100644 --- a/src/librustc_query_system/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs diff --git a/src/librustc_query_system/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index 549056570f9..549056570f9 100644 --- a/src/librustc_query_system/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs diff --git a/src/librustc_query_system/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 190312bb330..190312bb330 100644 --- a/src/librustc_query_system/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs diff --git a/src/librustc_query_system/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 49097725bc9..49097725bc9 100644 --- a/src/librustc_query_system/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs diff --git a/src/librustc_query_system/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index ae042cc8081..ae042cc8081 100644 --- a/src/librustc_query_system/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml new file mode 100644 index 00000000000..821f9ea4738 --- /dev/null +++ b/compiler/rustc_resolve/Cargo.toml @@ -0,0 +1,29 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_resolve" +version = "0.0.0" +edition = "2018" + +[lib] +test = false +doctest = false + +[dependencies] +bitflags = "1.2.1" +tracing = "0.1" +rustc_ast = { path = "../rustc_ast" } +rustc_arena = { path = "../rustc_arena" } +rustc_middle = { path = "../rustc_middle" } +rustc_ast_lowering = { path = "../rustc_ast_lowering" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_expand = { path = "../rustc_expand" } +rustc_feature = { path = "../rustc_feature" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_metadata = { path = "../rustc_metadata" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 761724be57d..761724be57d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs diff --git a/src/librustc_resolve/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 5624a6b6acc..5624a6b6acc 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs diff --git a/src/librustc_resolve/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 5d5088de31b..5d5088de31b 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs diff --git a/src/librustc_resolve/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 48e1068b8da..48e1068b8da 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs diff --git a/src/librustc_resolve/imports.rs b/compiler/rustc_resolve/src/imports.rs index b02fc427d60..b02fc427d60 100644 --- a/src/librustc_resolve/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs diff --git a/src/librustc_resolve/late.rs b/compiler/rustc_resolve/src/late.rs index d113eb22aba..2b2123e295d 100644 --- a/src/librustc_resolve/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -378,6 +378,9 @@ struct DiagnosticMetadata<'ast> { /// Only used for better errors on `let <pat>: <expr, not type>;`. current_let_binding: Option<(Span, Option<Span>, Option<Span>)>, + + /// Used to detect possible `if let` written without `let` and to provide structured suggestion. + in_if_condition: Option<&'ast Expr>, } struct LateResolutionVisitor<'a, 'b, 'ast> { @@ -403,7 +406,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> { /// /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items. /// In most cases this will be `None`, in which case errors will always be reported. - /// If it is `Some(_)`, then it will be updated when entering a nested function or trait body. + /// If it is `true`, then it will be updated when entering a nested function or trait body. in_func_body: bool, } @@ -2199,7 +2202,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::If(ref cond, ref then, ref opt_else) => { self.with_rib(ValueNS, NormalRibKind, |this| { + let old = this.diagnostic_metadata.in_if_condition.replace(cond); this.visit_expr(cond); + this.diagnostic_metadata.in_if_condition = old; this.visit_block(then); }); if let Some(expr) = opt_else { diff --git a/src/librustc_resolve/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d392967af38..8cb6b6553ff 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -176,6 +176,19 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { let code = source.error_code(res.is_some()); let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code); + match (source, self.diagnostic_metadata.in_if_condition) { + (PathSource::Expr(_), Some(Expr { span, kind: ExprKind::Assign(..), .. })) => { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "you might have meant to use pattern matching", + "let ".to_string(), + Applicability::MaybeIncorrect, + ); + self.r.session.if_let_suggestions.borrow_mut().insert(*span); + } + _ => {} + } + let is_assoc_fn = self.self_type_is_available(span); // Emit help message for fake-self from other languages (e.g., `this` in Javascript). if ["this", "my"].contains(&&*item_str.as_str()) && is_assoc_fn { diff --git a/src/librustc_resolve/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 31360d47473..31360d47473 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs diff --git a/src/librustc_resolve/lib.rs b/compiler/rustc_resolve/src/lib.rs index 5892edf7652..50729086ec6 100644 --- a/src/librustc_resolve/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -867,6 +867,12 @@ pub struct ExternPreludeEntry<'a> { pub introduced_by_item: bool, } +/// Used for better errors for E0773 +enum BuiltinMacroState { + NotYetSeen(SyntaxExtension), + AlreadySeen(Span), +} + /// The main resolver class. /// /// This is the visitor that walks the whole crate. @@ -960,7 +966,7 @@ pub struct Resolver<'a> { crate_loader: CrateLoader<'a>, macro_names: FxHashSet<Ident>, - builtin_macros: FxHashMap<Symbol, SyntaxExtension>, + builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, registered_attrs: FxHashSet<Ident>, registered_tools: FxHashSet<Ident>, macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>, diff --git a/src/librustc_resolve/macros.rs b/compiler/rustc_resolve/src/macros.rs index 51518d63ae9..bea71389647 100644 --- a/src/librustc_resolve/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -3,7 +3,7 @@ use crate::imports::ImportResolver; use crate::Namespace::*; -use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy}; +use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BuiltinMacroState, Determinacy}; use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc_ast::{self as ast, NodeId}; @@ -11,6 +11,7 @@ use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_pretty::pprust; use rustc_attr::StabilityLevel; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::struct_span_err; use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension}; use rustc_expand::compile_declarative_macro; use rustc_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind}; @@ -166,7 +167,7 @@ impl<'a> ResolverExpand for Resolver<'a> { } fn register_builtin_macro(&mut self, ident: Ident, ext: SyntaxExtension) { - if self.builtin_macros.insert(ident.name, ext).is_some() { + if self.builtin_macros.insert(ident.name, BuiltinMacroState::NotYetSeen(ext)).is_some() { self.session .span_err(ident.span, &format!("built-in macro `{}` was already defined", ident)); } @@ -1076,10 +1077,23 @@ impl<'a> Resolver<'a> { if result.is_builtin { // The macro was marked with `#[rustc_builtin_macro]`. - if let Some(ext) = self.builtin_macros.remove(&item.ident.name) { + if let Some(builtin_macro) = self.builtin_macros.get_mut(&item.ident.name) { // The macro is a built-in, replace its expander function // while still taking everything else from the source code. - result.kind = ext.kind; + // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'. + match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) { + BuiltinMacroState::NotYetSeen(ext) => result.kind = ext.kind, + BuiltinMacroState::AlreadySeen(span) => { + struct_span_err!( + self.session, + item.span, + E0773, + "attempted to define built-in macro more than once" + ) + .span_note(span, "previously defined here") + .emit(); + } + } } else { let msg = format!("cannot find a built-in macro with name `{}`", item.ident); self.session.span_err(item.span, &msg); diff --git a/compiler/rustc_save_analysis/Cargo.toml b/compiler/rustc_save_analysis/Cargo.toml new file mode 100644 index 00000000000..da1bed37a96 --- /dev/null +++ b/compiler/rustc_save_analysis/Cargo.toml @@ -0,0 +1,20 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_save_analysis" +version = "0.0.0" +edition = "2018" + +[dependencies] +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_ast = { path = "../rustc_ast" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_lexer = { path = "../rustc_lexer" } +serde_json = "1" +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rls-data = "0.19" +rls-span = "0.5" diff --git a/src/librustc_save_analysis/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index ce484858cbb..ce484858cbb 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs diff --git a/src/librustc_save_analysis/dumper.rs b/compiler/rustc_save_analysis/src/dumper.rs index 5a2628287d6..5a2628287d6 100644 --- a/src/librustc_save_analysis/dumper.rs +++ b/compiler/rustc_save_analysis/src/dumper.rs diff --git a/src/librustc_save_analysis/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 629051c1820..629051c1820 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs diff --git a/src/librustc_save_analysis/sig.rs b/compiler/rustc_save_analysis/src/sig.rs index 6dd7f89d594..6dd7f89d594 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/compiler/rustc_save_analysis/src/sig.rs diff --git a/src/librustc_save_analysis/span_utils.rs b/compiler/rustc_save_analysis/src/span_utils.rs index edcd4925773..edcd4925773 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/compiler/rustc_save_analysis/src/span_utils.rs diff --git a/src/librustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 939e6a59ba0..16c5dff7341 100644 --- a/src/librustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -4,13 +4,9 @@ name = "rustc_serialize" version = "0.0.0" edition = "2018" -[lib] -name = "rustc_serialize" -path = "lib.rs" - [dependencies] indexmap = "1" smallvec = { version = "1.0", features = ["union", "may_dangle"] } [dev-dependencies] -rustc_macros = { path = "../librustc_macros" } +rustc_macros = { path = "../rustc_macros" } diff --git a/src/librustc_serialize/collection_impls.rs b/compiler/rustc_serialize/src/collection_impls.rs index 3d274cb0150..3d274cb0150 100644 --- a/src/librustc_serialize/collection_impls.rs +++ b/compiler/rustc_serialize/src/collection_impls.rs diff --git a/src/librustc_serialize/json.rs b/compiler/rustc_serialize/src/json.rs index 6c8965aa2e3..6c8965aa2e3 100644 --- a/src/librustc_serialize/json.rs +++ b/compiler/rustc_serialize/src/json.rs diff --git a/src/librustc_serialize/json/tests.rs b/compiler/rustc_serialize/src/json/tests.rs index 01678fbf0b7..01678fbf0b7 100644 --- a/src/librustc_serialize/json/tests.rs +++ b/compiler/rustc_serialize/src/json/tests.rs diff --git a/src/librustc_serialize/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index 1fe6a309e96..1fe6a309e96 100644 --- a/src/librustc_serialize/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs diff --git a/src/librustc_serialize/lib.rs b/compiler/rustc_serialize/src/lib.rs index 265b3b95e95..265b3b95e95 100644 --- a/src/librustc_serialize/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs diff --git a/src/librustc_serialize/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index fa4423e261d..fa4423e261d 100644 --- a/src/librustc_serialize/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs diff --git a/src/librustc_serialize/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index c0e23b89a60..c0e23b89a60 100644 --- a/src/librustc_serialize/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs diff --git a/src/librustc_serialize/tests/json.rs b/compiler/rustc_serialize/tests/json.rs index e3a823127d9..e3a823127d9 100644 --- a/src/librustc_serialize/tests/json.rs +++ b/compiler/rustc_serialize/tests/json.rs diff --git a/src/librustc_serialize/tests/leb128.rs b/compiler/rustc_serialize/tests/leb128.rs index b0f7e785b78..b0f7e785b78 100644 --- a/src/librustc_serialize/tests/leb128.rs +++ b/compiler/rustc_serialize/tests/leb128.rs diff --git a/src/librustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs index 13b3676a56c..13b3676a56c 100644 --- a/src/librustc_serialize/tests/opaque.rs +++ b/compiler/rustc_serialize/tests/opaque.rs diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml new file mode 100644 index 00000000000..cdff1662fdb --- /dev/null +++ b/compiler/rustc_session/Cargo.toml @@ -0,0 +1,20 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_session" +version = "0.0.0" +edition = "2018" + +[dependencies] +bitflags = "1.2.1" +getopts = "0.2" +rustc_macros = { path = "../rustc_macros" } +tracing = "0.1" +rustc_errors = { path = "../rustc_errors" } +rustc_feature = { path = "../rustc_feature" } +rustc_target = { path = "../rustc_target" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_span = { path = "../rustc_span" } +rustc_fs_util = { path = "../rustc_fs_util" } +num_cpus = "1.0" +rustc_ast = { path = "../rustc_ast" } diff --git a/src/librustc_session/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs index 0eec12aa03f..0eec12aa03f 100644 --- a/src/librustc_session/cgu_reuse_tracker.rs +++ b/compiler/rustc_session/src/cgu_reuse_tracker.rs diff --git a/src/librustc_session/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index c263da69c35..c263da69c35 100644 --- a/src/librustc_session/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs diff --git a/src/librustc_session/config.rs b/compiler/rustc_session/src/config.rs index 1808a0ca59b..6861314a88f 100644 --- a/src/librustc_session/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -163,6 +163,21 @@ pub enum LtoCli { Unspecified, } +/// The different settings that the `-Z dump_mir_spanview` flag can have. `Statement` generates a +/// document highlighting each span of every statement (including terminators). `Terminator` and +/// `Block` highlight a single span per `BasicBlock`: the span of the block's `Terminator`, or a +/// computed span for the block, representing the entire range, covering the block's terminator and +/// all of its statements. +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum MirSpanview { + /// Default `-Z dump_mir_spanview` or `-Z dump_mir_spanview=statement` + Statement, + /// `-Z dump_mir_spanview=terminator` + Terminator, + /// `-Z dump_mir_spanview=block` + Block, +} + #[derive(Clone, PartialEq, Hash)] pub enum LinkerPluginLto { LinkerPlugin(PathBuf), @@ -1718,20 +1733,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { ); } - // `-Z instrument-coverage` implies: - // * `-Z symbol-mangling-version=v0` - to ensure consistent and reversible name mangling. - // Note, LLVM coverage tools can analyze coverage over multiple runs, including some - // changes to source code; so mangled names must be consistent across compilations. - // * `-C link-dead-code` - so unexecuted code is still counted as zero, rather than be - // optimized out. Note that instrumenting dead code can be explicitly disabled with: - // `-Z instrument-coverage -C link-dead-code=no`. + // `-Z instrument-coverage` implies `-Z symbol-mangling-version=v0` - to ensure consistent + // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over + // multiple runs, including some changes to source code; so mangled names must be consistent + // across compilations. debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0; - if cg.link_dead_code == None { - // FIXME(richkadel): Investigate if the `instrument-coverage` implementation can - // inject ["zero counters"](https://llvm.org/docs/CoverageMappingFormat.html#counter) - // in the coverage map when "dead code" is removed, rather than forcing `link-dead-code`. - cg.link_dead_code = Some(true); - } } if !cg.embed_bitcode { diff --git a/src/librustc_session/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 284fca652ec..284fca652ec 100644 --- a/src/librustc_session/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs diff --git a/src/librustc_session/lib.rs b/compiler/rustc_session/src/lib.rs index c2ea141a06f..a808261798d 100644 --- a/src/librustc_session/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,4 +1,5 @@ #![feature(crate_visibility_modifier)] +#![feature(once_cell)] #![feature(or_patterns)] #[macro_use] diff --git a/src/librustc_session/lint.rs b/compiler/rustc_session/src/lint.rs index 0dcbee08abe..0dcbee08abe 100644 --- a/src/librustc_session/lint.rs +++ b/compiler/rustc_session/src/lint.rs diff --git a/src/librustc_session/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs index 2db4d2a7f51..2db4d2a7f51 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/compiler/rustc_session/src/lint/builtin.rs diff --git a/src/librustc_session/options.rs b/compiler/rustc_session/src/options.rs index d05f1a3f34b..a28c17917df 100644 --- a/src/librustc_session/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -255,6 +255,7 @@ macro_rules! options { pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; + pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0"; pub const parse_lto: &str = @@ -551,6 +552,36 @@ macro_rules! options { } } + fn parse_mir_spanview(slot: &mut Option<MirSpanview>, v: Option<&str>) -> bool { + if v.is_some() { + let mut bool_arg = None; + if parse_opt_bool(&mut bool_arg, v) { + *slot = if bool_arg.unwrap() { + Some(MirSpanview::Statement) + } else { + None + }; + return true + } + } + + let v = match v { + None => { + *slot = Some(MirSpanview::Statement); + return true; + } + Some(v) => v, + }; + + *slot = Some(match v.trim_end_matches("s") { + "statement" | "stmt" => MirSpanview::Statement, + "terminator" | "term" => MirSpanview::Terminator, + "block" | "basicblock" => MirSpanview::Block, + _ => return false, + }); + true + } + fn parse_treat_err_as_bug(slot: &mut Option<usize>, v: Option<&str>) -> bool { match v { Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 } @@ -719,6 +750,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "extra arguments to append to the linker invocation (space separated)"), link_dead_code: Option<bool> = (None, parse_opt_bool, [UNTRACKED], "keep dead code at link time (useful for code coverage) (default: no)"), + link_self_contained: Option<bool> = (None, parse_opt_bool, [UNTRACKED], + "control whether to link Rust provided C objects/libraries or rely + on C toolchain installed in the system"), linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED], "system linker to link outputs with"), linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED], @@ -849,6 +883,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "exclude the pass number when dumping MIR (used in tests) (default: no)"), dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], "in addition to `.mir` files, create graphviz `.dot` files (default: no)"), + dump_mir_spanview: Option<MirSpanview> = (None, parse_mir_spanview, [UNTRACKED], + "in addition to `.mir` files, create `.html` files to view spans for \ + all `statement`s (including terminators), only `terminator` spans, or \ + computed `block` spans (one span encompassing a block's terminator and \ + all statements)."), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emit a section containing stack size metadata (default: no)"), fewer_names: bool = (false, parse_bool, [TRACKED], @@ -885,18 +924,15 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "instrument the generated code to support LLVM source-based code coverage \ reports (note, the compiler build config must include `profiler = true`, \ and is mutually exclusive with `-C profile-generate`/`-C profile-use`); \ - implies `-C link-dead-code` (unless explicitly disabled)` and \ - `-Z symbol-mangling-version=v0`; and disables/overrides some optimization \ - options (default: no)"), + implies `-C link-dead-code` (unless targeting MSVC, or explicitly disabled) \ + and `-Z symbol-mangling-version=v0`; disables/overrides some Rust \ + optimizations (default: no)"), instrument_mcount: bool = (false, parse_bool, [TRACKED], "insert function instrument code for mcount-based tracing (default: no)"), keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED], "keep hygiene data after analysis (default: no)"), link_native_libraries: bool = (true, parse_bool, [UNTRACKED], "link native libraries in the linker invocation (default: yes)"), - link_self_contained: Option<bool> = (None, parse_opt_bool, [TRACKED], - "control whether to link Rust provided C objects/libraries or rely - on C toolchain installed in the system"), link_only: bool = (false, parse_bool, [TRACKED], "link the `.rlink` file generated by `-Z no-link` (default: no)"), llvm_time_trace: bool = (false, parse_bool, [UNTRACKED], @@ -967,6 +1003,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "print the result of the monomorphization collection pass"), print_type_sizes: bool = (false, parse_bool, [UNTRACKED], "print layout information for each type encountered (default: no)"), + proc_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], + "show backtraces for panics during proc-macro execution (default: no)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code (default: no)"), profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], diff --git a/src/librustc_session/output.rs b/compiler/rustc_session/src/output.rs index bf9c96c6c94..bf9c96c6c94 100644 --- a/src/librustc_session/output.rs +++ b/compiler/rustc_session/src/output.rs diff --git a/src/librustc_session/parse.rs b/compiler/rustc_session/src/parse.rs index 6f10d0c4b89..6f10d0c4b89 100644 --- a/src/librustc_session/parse.rs +++ b/compiler/rustc_session/src/parse.rs diff --git a/src/librustc_session/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index e12364b7dac..e12364b7dac 100644 --- a/src/librustc_session/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs diff --git a/src/librustc_session/session.rs b/compiler/rustc_session/src/session.rs index c006e593e47..db2059251c0 100644 --- a/src/librustc_session/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -213,6 +213,9 @@ pub struct Session { known_attrs: Lock<MarkedAttrs>, used_attrs: Lock<MarkedAttrs>, + + /// `Span`s for `if` conditions that we have suggested turning into `if let`. + pub if_let_suggestions: Lock<FxHashSet<Span>>, } pub struct PerfStats { @@ -1021,6 +1024,40 @@ impl Session { || self.opts.debugging_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY) } + pub fn link_dead_code(&self) -> bool { + match self.opts.cg.link_dead_code { + Some(explicitly_set) => explicitly_set, + None => { + self.opts.debugging_opts.instrument_coverage + && !self.target.target.options.is_like_msvc + // Issue #76038: (rustc `-Clink-dead-code` causes MSVC linker to produce invalid + // binaries when LLVM InstrProf counters are enabled). As described by this issue, + // the "link dead code" option produces incorrect binaries when compiled and linked + // under MSVC. The resulting Rust programs typically crash with a segmentation + // fault, or produce an empty "*.profraw" file (profiling counter results normally + // generated during program exit). + // + // If not targeting MSVC, `-Z instrument-coverage` implies `-C link-dead-code`, so + // unexecuted code is still counted as zero, rather than be optimized out. Note that + // instrumenting dead code can be explicitly disabled with: + // + // `-Z instrument-coverage -C link-dead-code=no`. + // + // FIXME(richkadel): Investigate if `instrument-coverage` implementation can inject + // [zero counters](https://llvm.org/docs/CoverageMappingFormat.html#counter) in the + // coverage map when "dead code" is removed, rather than forcing `link-dead-code`. + // This may not be possible, however, if (as it seems to appear) the "dead code" + // that would otherwise not be linked is only identified as "dead" by the native + // linker. If that's the case, I believe it is too late for the Rust compiler to + // leverage any information it might be able to get from the linker regarding what + // code is dead, to be able to add those counters. + // + // On the other hand, if any Rust compiler passes are optimizing out dead code blocks + // we should inject "zero" counters for those code regions. + } + } + } + pub fn mark_attr_known(&self, attr: &Attribute) { self.known_attrs.lock().mark(attr) } @@ -1354,6 +1391,7 @@ pub fn build_session( target_features: FxHashSet::default(), known_attrs: Lock::new(MarkedAttrs::new()), used_attrs: Lock::new(MarkedAttrs::new()), + if_let_suggestions: Default::default(), }; validate_commandline_args_with_session_available(&sess); @@ -1428,20 +1466,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { ); } - // FIXME(richkadel): See `src/test/run-make-fulldeps/instrument-coverage/Makefile`. After - // compiling with `-Zinstrument-coverage`, the resulting binary generates a segfault during - // the program's exit process (likely while attempting to generate the coverage stats in - // the "*.profraw" file). An investigation to resolve the problem on Windows is ongoing, - // but until this is resolved, the option is disabled on Windows, and the test is skipped - // when targeting `MSVC`. - if sess.opts.debugging_opts.instrument_coverage && sess.target.target.options.is_like_msvc { - sess.warn( - "Rust source-based code coverage instrumentation (with `-Z instrument-coverage`) \ - is not yet supported on Windows when targeting MSVC. The resulting binaries will \ - still be instrumented for experimentation purposes, but may not execute correctly.", - ); - } - const ASAN_SUPPORTED_TARGETS: &[&str] = &[ "aarch64-fuchsia", "aarch64-unknown-linux-gnu", diff --git a/src/librustc_session/utils.rs b/compiler/rustc_session/src/utils.rs index 15447c01d1e..15447c01d1e 100644 --- a/src/librustc_session/utils.rs +++ b/compiler/rustc_session/src/utils.rs diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml new file mode 100644 index 00000000000..1abfd50f003 --- /dev/null +++ b/compiler/rustc_span/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_span" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_serialize = { path = "../rustc_serialize" } +rustc_macros = { path = "../rustc_macros" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } +rustc_arena = { path = "../rustc_arena" } +scoped-tls = "1.0" +unicode-width = "0.1.4" +cfg-if = "0.1.2" +tracing = "0.1" +sha-1 = "0.8" +md-5 = "0.8" diff --git a/src/librustc_span/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs index b4beb3dc376..b4beb3dc376 100644 --- a/src/librustc_span/analyze_source_file.rs +++ b/compiler/rustc_span/src/analyze_source_file.rs diff --git a/src/librustc_span/analyze_source_file/tests.rs b/compiler/rustc_span/src/analyze_source_file/tests.rs index cb418a4bdaf..cb418a4bdaf 100644 --- a/src/librustc_span/analyze_source_file/tests.rs +++ b/compiler/rustc_span/src/analyze_source_file/tests.rs diff --git a/src/librustc_span/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs index 68b0bd1a574..68b0bd1a574 100644 --- a/src/librustc_span/caching_source_map_view.rs +++ b/compiler/rustc_span/src/caching_source_map_view.rs diff --git a/src/librustc_span/def_id.rs b/compiler/rustc_span/src/def_id.rs index aae778217d3..aae778217d3 100644 --- a/src/librustc_span/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs diff --git a/src/librustc_span/edition.rs b/compiler/rustc_span/src/edition.rs index 4d0c92f51d7..4d0c92f51d7 100644 --- a/src/librustc_span/edition.rs +++ b/compiler/rustc_span/src/edition.rs diff --git a/src/librustc_span/fatal_error.rs b/compiler/rustc_span/src/fatal_error.rs index 718c0ddbc63..718c0ddbc63 100644 --- a/src/librustc_span/fatal_error.rs +++ b/compiler/rustc_span/src/fatal_error.rs diff --git a/src/librustc_span/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 942c6648340..942c6648340 100644 --- a/src/librustc_span/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs diff --git a/src/librustc_span/lib.rs b/compiler/rustc_span/src/lib.rs index c654dade2ab..b478a1d15c5 100644 --- a/src/librustc_span/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -400,6 +400,13 @@ impl Span { span.with_lo(span.hi) } + #[inline] + /// Returns true if hi == lo + pub fn is_empty(&self) -> bool { + let span = self.data(); + span.hi == span.lo + } + /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { if self.is_dummy() { other } else { self } diff --git a/src/librustc_span/source_map.rs b/compiler/rustc_span/src/source_map.rs index 7c656db22ed..37596b8ef6f 100644 --- a/src/librustc_span/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -487,6 +487,15 @@ impl SourceMap { } } + /// Returns a new `Span` covering the start and end `BytePos`s of the file containing the given + /// `pos`. This can be used to quickly determine if another `BytePos` or `Span` is from the same + /// file. + pub fn lookup_file_span(&self, pos: BytePos) -> Span { + let idx = self.lookup_source_file_idx(pos); + let SourceFile { start_pos, end_pos, .. } = *(*self.files.borrow().source_files)[idx]; + Span::with_root_ctxt(start_pos, end_pos) + } + /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If /// there are gaps between LHS and RHS, the resulting union will cross these gaps. /// For this to work, diff --git a/src/librustc_span/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index b8459eee4ec..b8459eee4ec 100644 --- a/src/librustc_span/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs diff --git a/src/librustc_span/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index b05e01d666b..b05e01d666b 100644 --- a/src/librustc_span/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs diff --git a/src/librustc_span/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5092b945f72..5092b945f72 100644 --- a/src/librustc_span/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs diff --git a/src/librustc_span/symbol/tests.rs b/compiler/rustc_span/src/symbol/tests.rs index 47da03424b7..47da03424b7 100644 --- a/src/librustc_span/symbol/tests.rs +++ b/compiler/rustc_span/src/symbol/tests.rs diff --git a/src/librustc_span/tests.rs b/compiler/rustc_span/src/tests.rs index 3c8eb8bcd31..3c8eb8bcd31 100644 --- a/src/librustc_span/tests.rs +++ b/compiler/rustc_span/src/tests.rs diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml new file mode 100644 index 00000000000..c0dacd24c38 --- /dev/null +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_symbol_mangling" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +tracing = "0.1" +punycode = "0.4.0" +rustc-demangle = "0.1.16" + +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +rustc_middle = { path = "../rustc_middle" } +rustc_hir = { path = "../rustc_hir" } +rustc_target = { path = "../rustc_target" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_session = { path = "../rustc_session" } diff --git a/src/librustc_symbol_mangling/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 24356844baf..24356844baf 100644 --- a/src/librustc_symbol_mangling/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs diff --git a/src/librustc_symbol_mangling/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 296b40c4e39..296b40c4e39 100644 --- a/src/librustc_symbol_mangling/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs diff --git a/src/librustc_symbol_mangling/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index 24850a8a0d2..24850a8a0d2 100644 --- a/src/librustc_symbol_mangling/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs diff --git a/src/librustc_symbol_mangling/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index f01c3da8b5f..f01c3da8b5f 100644 --- a/src/librustc_symbol_mangling/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml new file mode 100644 index 00000000000..2d7d9f1d82d --- /dev/null +++ b/compiler/rustc_target/Cargo.toml @@ -0,0 +1,14 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_target" +version = "0.0.0" +edition = "2018" + +[dependencies] +bitflags = "1.2.1" +tracing = "0.1" +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } +rustc_index = { path = "../rustc_index" } diff --git a/src/librustc_target/README.md b/compiler/rustc_target/README.md index ac1e03385d1..ac1e03385d1 100644 --- a/src/librustc_target/README.md +++ b/compiler/rustc_target/README.md diff --git a/src/librustc_target/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs index 1ab7722edab..1ab7722edab 100644 --- a/src/librustc_target/abi/call/aarch64.rs +++ b/compiler/rustc_target/src/abi/call/aarch64.rs diff --git a/src/librustc_target/abi/call/amdgpu.rs b/compiler/rustc_target/src/abi/call/amdgpu.rs index 0b4f279fece..0b4f279fece 100644 --- a/src/librustc_target/abi/call/amdgpu.rs +++ b/compiler/rustc_target/src/abi/call/amdgpu.rs diff --git a/src/librustc_target/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs index 26fed3bae4e..26fed3bae4e 100644 --- a/src/librustc_target/abi/call/arm.rs +++ b/compiler/rustc_target/src/abi/call/arm.rs diff --git a/src/librustc_target/abi/call/avr.rs b/compiler/rustc_target/src/abi/call/avr.rs index c1f7a1e3af5..c1f7a1e3af5 100644 --- a/src/librustc_target/abi/call/avr.rs +++ b/compiler/rustc_target/src/abi/call/avr.rs diff --git a/src/librustc_target/abi/call/hexagon.rs b/compiler/rustc_target/src/abi/call/hexagon.rs index 8028443b8a6..8028443b8a6 100644 --- a/src/librustc_target/abi/call/hexagon.rs +++ b/compiler/rustc_target/src/abi/call/hexagon.rs diff --git a/src/librustc_target/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs index 733a7328bd3..733a7328bd3 100644 --- a/src/librustc_target/abi/call/mips.rs +++ b/compiler/rustc_target/src/abi/call/mips.rs diff --git a/src/librustc_target/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs index 917dd104d14..917dd104d14 100644 --- a/src/librustc_target/abi/call/mips64.rs +++ b/compiler/rustc_target/src/abi/call/mips64.rs diff --git a/src/librustc_target/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 8f7e2bba5aa..8f7e2bba5aa 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs diff --git a/src/librustc_target/abi/call/msp430.rs b/compiler/rustc_target/src/abi/call/msp430.rs index 3004bb9ff5d..3004bb9ff5d 100644 --- a/src/librustc_target/abi/call/msp430.rs +++ b/compiler/rustc_target/src/abi/call/msp430.rs diff --git a/src/librustc_target/abi/call/nvptx.rs b/compiler/rustc_target/src/abi/call/nvptx.rs index 693337f0e52..693337f0e52 100644 --- a/src/librustc_target/abi/call/nvptx.rs +++ b/compiler/rustc_target/src/abi/call/nvptx.rs diff --git a/src/librustc_target/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs index b9c9296dbac..b9c9296dbac 100644 --- a/src/librustc_target/abi/call/nvptx64.rs +++ b/compiler/rustc_target/src/abi/call/nvptx64.rs diff --git a/src/librustc_target/abi/call/powerpc.rs b/compiler/rustc_target/src/abi/call/powerpc.rs index 27a5c6d2fc6..27a5c6d2fc6 100644 --- a/src/librustc_target/abi/call/powerpc.rs +++ b/compiler/rustc_target/src/abi/call/powerpc.rs diff --git a/src/librustc_target/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs index b740707320f..b740707320f 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/compiler/rustc_target/src/abi/call/powerpc64.rs diff --git a/src/librustc_target/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs index 2e10bed3bd4..2e10bed3bd4 100644 --- a/src/librustc_target/abi/call/riscv.rs +++ b/compiler/rustc_target/src/abi/call/riscv.rs diff --git a/src/librustc_target/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs index 005dcc62dfd..005dcc62dfd 100644 --- a/src/librustc_target/abi/call/s390x.rs +++ b/compiler/rustc_target/src/abi/call/s390x.rs diff --git a/src/librustc_target/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs index 733a7328bd3..733a7328bd3 100644 --- a/src/librustc_target/abi/call/sparc.rs +++ b/compiler/rustc_target/src/abi/call/sparc.rs diff --git a/src/librustc_target/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs index a647675e073..a647675e073 100644 --- a/src/librustc_target/abi/call/sparc64.rs +++ b/compiler/rustc_target/src/abi/call/sparc64.rs diff --git a/src/librustc_target/abi/call/wasm32.rs b/compiler/rustc_target/src/abi/call/wasm32.rs index 510f671a501..510f671a501 100644 --- a/src/librustc_target/abi/call/wasm32.rs +++ b/compiler/rustc_target/src/abi/call/wasm32.rs diff --git a/src/librustc_target/abi/call/wasm32_bindgen_compat.rs b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs index 59571fd9d48..59571fd9d48 100644 --- a/src/librustc_target/abi/call/wasm32_bindgen_compat.rs +++ b/compiler/rustc_target/src/abi/call/wasm32_bindgen_compat.rs diff --git a/src/librustc_target/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs index df3dd5d9208..df3dd5d9208 100644 --- a/src/librustc_target/abi/call/x86.rs +++ b/compiler/rustc_target/src/abi/call/x86.rs diff --git a/src/librustc_target/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs index 5f154dc1bc9..5f154dc1bc9 100644 --- a/src/librustc_target/abi/call/x86_64.rs +++ b/compiler/rustc_target/src/abi/call/x86_64.rs diff --git a/src/librustc_target/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs index 2aad641b1ec..2aad641b1ec 100644 --- a/src/librustc_target/abi/call/x86_win64.rs +++ b/compiler/rustc_target/src/abi/call/x86_win64.rs diff --git a/src/librustc_target/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 4b565dd246f..4b565dd246f 100644 --- a/src/librustc_target/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs diff --git a/src/librustc_target/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index e7c9edea765..e7c9edea765 100644 --- a/src/librustc_target/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs diff --git a/src/librustc_target/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 85a136b94aa..85a136b94aa 100644 --- a/src/librustc_target/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs diff --git a/src/librustc_target/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs index d41941d0b4c..d41941d0b4c 100644 --- a/src/librustc_target/asm/hexagon.rs +++ b/compiler/rustc_target/src/asm/hexagon.rs diff --git a/src/librustc_target/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index c22644bf813..c22644bf813 100644 --- a/src/librustc_target/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs diff --git a/src/librustc_target/asm/nvptx.rs b/compiler/rustc_target/src/asm/nvptx.rs index 43d16ae0f5d..43d16ae0f5d 100644 --- a/src/librustc_target/asm/nvptx.rs +++ b/compiler/rustc_target/src/asm/nvptx.rs diff --git a/src/librustc_target/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index ced7483b005..ced7483b005 100644 --- a/src/librustc_target/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs diff --git a/src/librustc_target/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 0f62c19e1a3..0f62c19e1a3 100644 --- a/src/librustc_target/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs diff --git a/src/librustc_target/lib.rs b/compiler/rustc_target/src/lib.rs index 5788e1e8385..5788e1e8385 100644 --- a/src/librustc_target/lib.rs +++ b/compiler/rustc_target/src/lib.rs diff --git a/src/librustc_target/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index 60daf10b36a..60daf10b36a 100644 --- a/src/librustc_target/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs index 21dcec8d5e3..21dcec8d5e3 100644 --- a/src/librustc_target/spec/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs diff --git a/src/librustc_target/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs index 2b0cd6cabf8..2b0cd6cabf8 100644 --- a/src/librustc_target/spec/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs diff --git a/src/librustc_target/spec/aarch64_fuchsia.rs b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs index aabfe458ca3..aabfe458ca3 100644 --- a/src/librustc_target/spec/aarch64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs diff --git a/src/librustc_target/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs index e4ecc7ac2dc..e4ecc7ac2dc 100644 --- a/src/librustc_target/spec/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs diff --git a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs index 8c03f1e8a7e..8c03f1e8a7e 100644 --- a/src/librustc_target/spec/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs diff --git a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs index 1278b89c7fd..1278b89c7fd 100644 --- a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_cloudabi.rs diff --git a/src/librustc_target/spec/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs index 5ae592c5139..5ae592c5139 100644 --- a/src/librustc_target/spec/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs diff --git a/src/librustc_target/spec/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs index e07b8f7a756..e07b8f7a756 100644 --- a/src/librustc_target/spec/aarch64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_hermit.rs diff --git a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs index 036162248c7..036162248c7 100644 --- a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs index dc613f35d1d..dc613f35d1d 100644 --- a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs index 8c2f6fcff73..8c2f6fcff73 100644 --- a/src/librustc_target/spec/aarch64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs diff --git a/src/librustc_target/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs index e012dce73fe..e012dce73fe 100644 --- a/src/librustc_target/spec/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs diff --git a/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs index e2aa6e3b8f5..e2aa6e3b8f5 100644 --- a/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs diff --git a/src/librustc_target/spec/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs index fd726c70f49..fd726c70f49 100644 --- a/src/librustc_target/spec/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs diff --git a/src/librustc_target/spec/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs index f347a2dba53..f347a2dba53 100644 --- a/src/librustc_target/spec/aarch64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_redox.rs diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs index 6a8d148259a..6a8d148259a 100644 --- a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs diff --git a/src/librustc_target/spec/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs index 05f5d7d3a8b..05f5d7d3a8b 100644 --- a/src/librustc_target/spec/aarch64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs diff --git a/src/librustc_target/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index 1e45739ca22..1e45739ca22 100644 --- a/src/librustc_target/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs diff --git a/src/librustc_target/spec/abi/tests.rs b/compiler/rustc_target/src/spec/abi/tests.rs index 8bea5e5efe3..8bea5e5efe3 100644 --- a/src/librustc_target/spec/abi/tests.rs +++ b/compiler/rustc_target/src/spec/abi/tests.rs diff --git a/src/librustc_target/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index 0ea99af83a1..0ea99af83a1 100644 --- a/src/librustc_target/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs diff --git a/src/librustc_target/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index e7b565ae9ca..e7b565ae9ca 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs diff --git a/src/librustc_target/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index 0d0a0da9d1c..0d0a0da9d1c 100644 --- a/src/librustc_target/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs diff --git a/src/librustc_target/spec/arm_base.rs b/compiler/rustc_target/src/spec/arm_base.rs index b74d80dc6bb..b74d80dc6bb 100644 --- a/src/librustc_target/spec/arm_base.rs +++ b/compiler/rustc_target/src/spec/arm_base.rs diff --git a/src/librustc_target/spec/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs index 7109d043f51..7109d043f51 100644 --- a/src/librustc_target/spec/arm_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs index 2e3bad83e25..2e3bad83e25 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs index f8e357cce66..f8e357cce66 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs index 75753af9f30..75753af9f30 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs index c74c88e3612..c74c88e3612 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs index e0d1f2653ce..e0d1f2653ce 100644 --- a/src/librustc_target/spec/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs index e2d37d45bf1..e2d37d45bf1 100644 --- a/src/librustc_target/spec/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs diff --git a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs index 2580e8b0f85..2580e8b0f85 100644 --- a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs diff --git a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs index f28421dc775..f28421dc775 100644 --- a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs diff --git a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs index fe1fa88883d..fe1fa88883d 100644 --- a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs index 1e06f837997..1e06f837997 100644 --- a/src/librustc_target/spec/armv6_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs index ef40085888c..ef40085888c 100644 --- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs diff --git a/src/librustc_target/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs index 393843526a8..393843526a8 100644 --- a/src/librustc_target/spec/armv7_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs diff --git a/src/librustc_target/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs index 38c6c31bd10..38c6c31bd10 100644 --- a/src/librustc_target/spec/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs diff --git a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs index e3f4fe0b2ef..e3f4fe0b2ef 100644 --- a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_cloudabi_eabihf.rs diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs index 80a9e6d7e3c..80a9e6d7e3c 100644 --- a/src/librustc_target/spec/armv7_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs index 0f175e9aef5..0f175e9aef5 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs index 27923457cd1..27923457cd1 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs index 3d1bf05237f..3d1bf05237f 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs index 03d7d88b0d6..03d7d88b0d6 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs diff --git a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs index 18fc9ed2ec6..18fc9ed2ec6 100644 --- a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs diff --git a/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs index 04d8702471a..04d8702471a 100644 --- a/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs diff --git a/src/librustc_target/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs index 1db279defff..1db279defff 100644 --- a/src/librustc_target/spec/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs diff --git a/src/librustc_target/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs index 22c2b306b43..22c2b306b43 100644 --- a/src/librustc_target/spec/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs index fed83997190..fed83997190 100644 --- a/src/librustc_target/spec/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs index 769ac13e515..769ac13e515 100644 --- a/src/librustc_target/spec/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs diff --git a/src/librustc_target/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs index 998a7b2e164..998a7b2e164 100644 --- a/src/librustc_target/spec/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs diff --git a/src/librustc_target/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs index d3dbc39c99d..d3dbc39c99d 100644 --- a/src/librustc_target/spec/asmjs_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs diff --git a/src/librustc_target/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index ff559c2bfd6..ff559c2bfd6 100644 --- a/src/librustc_target/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs diff --git a/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs index 5d22598b57b..5d22598b57b 100644 --- a/src/librustc_target/spec/avr_unknown_gnu_atmega328.rs +++ b/compiler/rustc_target/src/spec/avr_unknown_gnu_atmega328.rs diff --git a/src/librustc_target/spec/cloudabi_base.rs b/compiler/rustc_target/src/spec/cloudabi_base.rs index 39039435f58..39039435f58 100644 --- a/src/librustc_target/spec/cloudabi_base.rs +++ b/compiler/rustc_target/src/spec/cloudabi_base.rs diff --git a/src/librustc_target/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs index 8991691a9a3..8991691a9a3 100644 --- a/src/librustc_target/spec/crt_objects.rs +++ b/compiler/rustc_target/src/spec/crt_objects.rs diff --git a/src/librustc_target/spec/dragonfly_base.rs b/compiler/rustc_target/src/spec/dragonfly_base.rs index c7062e1ca51..c7062e1ca51 100644 --- a/src/librustc_target/spec/dragonfly_base.rs +++ b/compiler/rustc_target/src/spec/dragonfly_base.rs diff --git a/src/librustc_target/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs index d2a087ab62f..d2a087ab62f 100644 --- a/src/librustc_target/spec/freebsd_base.rs +++ b/compiler/rustc_target/src/spec/freebsd_base.rs diff --git a/src/librustc_target/spec/fuchsia_base.rs b/compiler/rustc_target/src/spec/fuchsia_base.rs index 6f432dc1171..6f432dc1171 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/compiler/rustc_target/src/spec/fuchsia_base.rs diff --git a/src/librustc_target/spec/haiku_base.rs b/compiler/rustc_target/src/spec/haiku_base.rs index 3d7ae6c302d..3d7ae6c302d 100644 --- a/src/librustc_target/spec/haiku_base.rs +++ b/compiler/rustc_target/src/spec/haiku_base.rs diff --git a/src/librustc_target/spec/hermit_base.rs b/compiler/rustc_target/src/spec/hermit_base.rs index e063c94cf2c..e063c94cf2c 100644 --- a/src/librustc_target/spec/hermit_base.rs +++ b/compiler/rustc_target/src/spec/hermit_base.rs diff --git a/src/librustc_target/spec/hermit_kernel_base.rs b/compiler/rustc_target/src/spec/hermit_kernel_base.rs index 01b9f75637f..01b9f75637f 100644 --- a/src/librustc_target/spec/hermit_kernel_base.rs +++ b/compiler/rustc_target/src/spec/hermit_kernel_base.rs diff --git a/src/librustc_target/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs index 0976acb4fb0..0976acb4fb0 100644 --- a/src/librustc_target/spec/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index a121d49769d..a121d49769d 100644 --- a/src/librustc_target/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs diff --git a/src/librustc_target/spec/i586_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i586_pc_windows_msvc.rs index ba712aced84..ba712aced84 100644 --- a/src/librustc_target/spec/i586_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i586_pc_windows_msvc.rs diff --git a/src/librustc_target/spec/i586_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i586_unknown_linux_gnu.rs index 49f4f2cb6b9..49f4f2cb6b9 100644 --- a/src/librustc_target/spec/i586_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i586_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/i586_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i586_unknown_linux_musl.rs index 0f2ccebd6da..0f2ccebd6da 100644 --- a/src/librustc_target/spec/i586_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i586_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index b7a34f9740a..b7a34f9740a 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs diff --git a/src/librustc_target/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs index 79242f24026..79242f24026 100644 --- a/src/librustc_target/spec/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/i686_linux_android.rs diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs index 33c9008bb14..33c9008bb14 100644 --- a/src/librustc_target/spec/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs index 9d0922b8ce5..9d0922b8ce5 100644 --- a/src/librustc_target/spec/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs diff --git a/src/librustc_target/spec/i686_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs index 729b1f68e00..729b1f68e00 100644 --- a/src/librustc_target/spec/i686_unknown_cloudabi.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_cloudabi.rs diff --git a/src/librustc_target/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index 60f2188514e..60f2188514e 100644 --- a/src/librustc_target/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs diff --git a/src/librustc_target/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs index 4dc27af30da..4dc27af30da 100644 --- a/src/librustc_target/spec/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs diff --git a/src/librustc_target/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index 0d578f22f98..0d578f22f98 100644 --- a/src/librustc_target/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index 699a0ab45e8..699a0ab45e8 100644 --- a/src/librustc_target/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index 88b1ae7d53c..88b1ae7d53c 100644 --- a/src/librustc_target/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs diff --git a/src/librustc_target/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index 829cd1ac1a3..829cd1ac1a3 100644 --- a/src/librustc_target/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/compiler/rustc_target/src/spec/i686_unknown_uefi.rs index 221d5f0785c..221d5f0785c 100644 --- a/src/librustc_target/spec/i686_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_uefi.rs diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs index 1c6d2e061bc..1c6d2e061bc 100644 --- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs index ed2dba53589..ed2dba53589 100644 --- a/src/librustc_target/spec/i686_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_msvc.rs diff --git a/src/librustc_target/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index f5f66cabb2c..f5f66cabb2c 100644 --- a/src/librustc_target/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs diff --git a/src/librustc_target/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs index 214142b88fc..214142b88fc 100644 --- a/src/librustc_target/spec/illumos_base.rs +++ b/compiler/rustc_target/src/spec/illumos_base.rs diff --git a/src/librustc_target/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs index 5caad10161d..5caad10161d 100644 --- a/src/librustc_target/spec/l4re_base.rs +++ b/compiler/rustc_target/src/spec/l4re_base.rs diff --git a/src/librustc_target/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index 52892fc3592..52892fc3592 100644 --- a/src/librustc_target/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 6d929d12447..6d929d12447 100644 --- a/src/librustc_target/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs diff --git a/src/librustc_target/spec/linux_musl_base.rs b/compiler/rustc_target/src/spec/linux_musl_base.rs index b90e91d2901..b90e91d2901 100644 --- a/src/librustc_target/spec/linux_musl_base.rs +++ b/compiler/rustc_target/src/spec/linux_musl_base.rs diff --git a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs index b2ea8a6f388..b2ea8a6f388 100644 --- a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs diff --git a/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs index 17584de1144..17584de1144 100644 --- a/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs diff --git a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs index 48aea4a39b0..48aea4a39b0 100644 --- a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs diff --git a/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs index c7a849a1641..c7a849a1641 100644 --- a/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs diff --git a/src/librustc_target/spec/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs index e360abdb38d..e360abdb38d 100644 --- a/src/librustc_target/spec/mips_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs index c8d97e600d4..c8d97e600d4 100644 --- a/src/librustc_target/spec/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs index 8116b8c9cc8..8116b8c9cc8 100644 --- a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs diff --git a/src/librustc_target/spec/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs index b3bda97c8a5..b3bda97c8a5 100644 --- a/src/librustc_target/spec/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs diff --git a/src/librustc_target/spec/mipsel_sony_psp_linker_script.ld b/compiler/rustc_target/src/spec/mipsel_sony_psp_linker_script.ld index 1bd436d6f94..1bd436d6f94 100644 --- a/src/librustc_target/spec/mipsel_sony_psp_linker_script.ld +++ b/compiler/rustc_target/src/spec/mipsel_sony_psp_linker_script.ld diff --git a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs index 7e9d8cd942a..7e9d8cd942a 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs index f70cc13224f..f70cc13224f 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs index a8152011efa..a8152011efa 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_linux_uclibc.rs diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs index 36b83c63fca..36b83c63fca 100644 --- a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs index 717ae3f1d20..717ae3f1d20 100644 --- a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6el_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs index 3f7d233e55f..3f7d233e55f 100644 --- a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs index 4f41b8323a9..4f41b8323a9 100644 --- a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs diff --git a/src/librustc_target/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index d6e8b304380..d6e8b304380 100644 --- a/src/librustc_target/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs diff --git a/src/librustc_target/spec/msp430_none_elf.rs b/compiler/rustc_target/src/spec/msp430_none_elf.rs index f75697996ac..f75697996ac 100644 --- a/src/librustc_target/spec/msp430_none_elf.rs +++ b/compiler/rustc_target/src/spec/msp430_none_elf.rs diff --git a/src/librustc_target/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs index f57ef87cf12..f57ef87cf12 100644 --- a/src/librustc_target/spec/msvc_base.rs +++ b/compiler/rustc_target/src/spec/msvc_base.rs diff --git a/src/librustc_target/spec/netbsd_base.rs b/compiler/rustc_target/src/spec/netbsd_base.rs index 988346af2d7..988346af2d7 100644 --- a/src/librustc_target/spec/netbsd_base.rs +++ b/compiler/rustc_target/src/spec/netbsd_base.rs diff --git a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs index 0c8f2a34301..0c8f2a34301 100644 --- a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs diff --git a/src/librustc_target/spec/openbsd_base.rs b/compiler/rustc_target/src/spec/openbsd_base.rs index cadd14df693..cadd14df693 100644 --- a/src/librustc_target/spec/openbsd_base.rs +++ b/compiler/rustc_target/src/spec/openbsd_base.rs diff --git a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs index 60c15d6b7d2..60c15d6b7d2 100644 --- a/src/librustc_target/spec/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs index 5306d905c5d..5306d905c5d 100644 --- a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs index c3b956effae..c3b956effae 100644 --- a/src/librustc_target/spec/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index e00a927c3a4..e00a927c3a4 100644 --- a/src/librustc_target/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs index 90737994612..90737994612 100644 --- a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs index 1a1fccfab02..1a1fccfab02 100644 --- a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs index 2d4c5986637..2d4c5986637 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs index fabc4313bee..fabc4313bee 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs diff --git a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs index 240cbcbfe6e..240cbcbfe6e 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 6ca7053ced5..6ca7053ced5 100644 --- a/src/librustc_target/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index 2211dc29a5d..2211dc29a5d 100644 --- a/src/librustc_target/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index b10182c09ad..b10182c09ad 100644 --- a/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs diff --git a/src/librustc_target/spec/redox_base.rs b/compiler/rustc_target/src/spec/redox_base.rs index 18cafe654d1..18cafe654d1 100644 --- a/src/librustc_target/spec/redox_base.rs +++ b/compiler/rustc_target/src/spec/redox_base.rs diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs index 5b5e342000b..5b5e342000b 100644 --- a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs index 4cef5c42d8d..4cef5c42d8d 100644 --- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs index 8ad563e441d..8ad563e441d 100644 --- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs diff --git a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs index f7a93c916d1..f7a93c916d1 100644 --- a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs index 3aeb3f3ca72..3aeb3f3ca72 100644 --- a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs diff --git a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs index d8144964dc9..d8144964dc9 100644 --- a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs diff --git a/src/librustc_target/spec/riscv_base.rs b/compiler/rustc_target/src/spec/riscv_base.rs index 64cf890037e..64cf890037e 100644 --- a/src/librustc_target/spec/riscv_base.rs +++ b/compiler/rustc_target/src/spec/riscv_base.rs diff --git a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs index f259787e1d5..f259787e1d5 100644 --- a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/solaris_base.rs b/compiler/rustc_target/src/spec/solaris_base.rs index 3d7f0034b8b..3d7f0034b8b 100644 --- a/src/librustc_target/spec/solaris_base.rs +++ b/compiler/rustc_target/src/spec/solaris_base.rs diff --git a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs index c842b22d4e1..c842b22d4e1 100644 --- a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index aad85e852f0..aad85e852f0 100644 --- a/src/librustc_target/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs diff --git a/src/librustc_target/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs index 229e0621e0d..229e0621e0d 100644 --- a/src/librustc_target/spec/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs diff --git a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs index 162cd311a38..162cd311a38 100644 --- a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs index acc03fd0d79..acc03fd0d79 100644 --- a/src/librustc_target/spec/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs diff --git a/src/librustc_target/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index b2c2b8254d8..b2c2b8254d8 100644 --- a/src/librustc_target/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs diff --git a/src/librustc_target/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs index 2f7d15d5856..2f7d15d5856 100644 --- a/src/librustc_target/spec/thumb_base.rs +++ b/compiler/rustc_target/src/spec/thumb_base.rs diff --git a/src/librustc_target/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index a8c78f057fc..a8c78f057fc 100644 --- a/src/librustc_target/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs index 953d60fcc22..953d60fcc22 100644 --- a/src/librustc_target/spec/thumbv6m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs index 37828026fe1..37828026fe1 100644 --- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs diff --git a/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs index 29a4a9875e5..29a4a9875e5 100644 --- a/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs diff --git a/src/librustc_target/spec/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs index 9e085381953..9e085381953 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs diff --git a/src/librustc_target/spec/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs index 95b9b9d5b56..95b9b9d5b56 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs diff --git a/src/librustc_target/spec/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs index 528359ffad3..528359ffad3 100644 --- a/src/librustc_target/spec/thumbv7m_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs diff --git a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs index c52f077f6f1..c52f077f6f1 100644 --- a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs index 78936948e64..78936948e64 100644 --- a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs index f759c3eeb01..f759c3eeb01 100644 --- a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs diff --git a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs index 3f67c67b7bc..3f67c67b7bc 100644 --- a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs index 2f8103f0c70..2f8103f0c70 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs index 53a340230d6..53a340230d6 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs diff --git a/src/librustc_target/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index 3f7c78c8e7d..3f7c78c8e7d 100644 --- a/src/librustc_target/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs diff --git a/src/librustc_target/spec/vxworks_base.rs b/compiler/rustc_target/src/spec/vxworks_base.rs index 777bb58d7db..777bb58d7db 100644 --- a/src/librustc_target/spec/vxworks_base.rs +++ b/compiler/rustc_target/src/spec/vxworks_base.rs diff --git a/src/librustc_target/spec/wasm32_base.rs b/compiler/rustc_target/src/spec/wasm32_base.rs index 62fc8f06183..62fc8f06183 100644 --- a/src/librustc_target/spec/wasm32_base.rs +++ b/compiler/rustc_target/src/spec/wasm32_base.rs diff --git a/src/librustc_target/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index 1916639170e..1916639170e 100644 --- a/src/librustc_target/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index ded95a34d55..ded95a34d55 100644 --- a/src/librustc_target/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs diff --git a/src/librustc_target/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 0bba7bdd473..0bba7bdd473 100644 --- a/src/librustc_target/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs diff --git a/src/librustc_target/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index a864918655f..a864918655f 100644 --- a/src/librustc_target/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/compiler/rustc_target/src/spec/windows_msvc_base.rs index 77171f8672e..77171f8672e 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/compiler/rustc_target/src/spec/windows_msvc_base.rs diff --git a/src/librustc_target/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs index fd55a0fc6a1..fd55a0fc6a1 100644 --- a/src/librustc_target/spec/windows_uwp_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs index 04ffa1a0add..04ffa1a0add 100644 --- a/src/librustc_target/spec/windows_uwp_msvc_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 909aebec70b..909aebec70b 100644 --- a/src/librustc_target/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs diff --git a/src/librustc_target/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index cfcf856836b..cfcf856836b 100644 --- a/src/librustc_target/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs diff --git a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index c42d0911725..c42d0911725 100644 --- a/src/librustc_target/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs diff --git a/src/librustc_target/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index a56062c0b2b..a56062c0b2b 100644 --- a/src/librustc_target/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs index 3b5233a3e67..3b5233a3e67 100644 --- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs diff --git a/src/librustc_target/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs index 37b6d57366c..37b6d57366c 100644 --- a/src/librustc_target/spec/x86_64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs diff --git a/src/librustc_target/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index 74097f5bf6f..74097f5bf6f 100644 --- a/src/librustc_target/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs diff --git a/src/librustc_target/spec/x86_64_linux_kernel.rs b/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs index 65bb97d84aa..65bb97d84aa 100644 --- a/src/librustc_target/spec/x86_64_linux_kernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_kernel.rs diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs index 99af483f1d4..99af483f1d4 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs diff --git a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs index 75ff6b97a2e..75ff6b97a2e 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_msvc.rs diff --git a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs index fbade02c556..fbade02c556 100644 --- a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_rumprun_netbsd.rs diff --git a/src/librustc_target/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs index 53f4df96518..53f4df96518 100644 --- a/src/librustc_target/spec/x86_64_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs diff --git a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs index dbc5f965020..dbc5f965020 100644 --- a/src/librustc_target/spec/x86_64_unknown_cloudabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_cloudabi.rs diff --git a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index fd1871b1a57..fd1871b1a57 100644 --- a/src/librustc_target/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs diff --git a/src/librustc_target/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index a124f582bf3..a124f582bf3 100644 --- a/src/librustc_target/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs diff --git a/src/librustc_target/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs index 51237697714..51237697714 100644 --- a/src/librustc_target/spec/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs diff --git a/src/librustc_target/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs index 4a526f90ed5..4a526f90ed5 100644 --- a/src/librustc_target/spec/x86_64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs diff --git a/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs index c25cd0809ee..c25cd0809ee 100644 --- a/src/librustc_target/spec/x86_64_unknown_hermit_kernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit_kernel.rs diff --git a/src/librustc_target/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs index 2567ca47ef9..2567ca47ef9 100644 --- a/src/librustc_target/spec/x86_64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs diff --git a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs index cab19f149a7..cab19f149a7 100644 --- a/src/librustc_target/spec/x86_64_unknown_l4re_uclibc.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 29cbb777db5..29cbb777db5 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs diff --git a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index 0a37399e2fa..0a37399e2fa 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs diff --git a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index 3a22290da68..3a22290da68 100644 --- a/src/librustc_target/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs diff --git a/src/librustc_target/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index adf09c89c42..adf09c89c42 100644 --- a/src/librustc_target/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs diff --git a/src/librustc_target/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index dbd163db36b..dbd163db36b 100644 --- a/src/librustc_target/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs diff --git a/src/librustc_target/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index 3d40bafbe1f..3d40bafbe1f 100644 --- a/src/librustc_target/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs index 849227a574a..849227a574a 100644 --- a/src/librustc_target/spec/x86_64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs index 3bd18f23f6f..3bd18f23f6f 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs index 258df010aae..258df010aae 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_msvc.rs diff --git a/src/librustc_target/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index f1e27f4d8be..f1e27f4d8be 100644 --- a/src/librustc_target/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml new file mode 100644 index 00000000000..a72c172918b --- /dev/null +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -0,0 +1,25 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_trait_selection" +version = "0.0.0" +edition = "2018" + +[lib] +doctest = false + +[dependencies] +rustc_parse_format = { path = "../rustc_parse_format" } +tracing = "0.1" +rustc_attr = { path = "../rustc_attr" } +rustc_middle = { path = "../rustc_middle" } +rustc_ast = { path = "../rustc_ast" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_infer = { path = "../rustc_infer" } +rustc_macros = { path = "../rustc_macros" } +rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_trait_selection/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 02eefe56223..02eefe56223 100644 --- a/src/librustc_trait_selection/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs diff --git a/src/librustc_trait_selection/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 4ec1b29bca4..4ec1b29bca4 100644 --- a/src/librustc_trait_selection/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs diff --git a/src/librustc_trait_selection/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index b5882df4729..b5882df4729 100644 --- a/src/librustc_trait_selection/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs diff --git a/src/librustc_trait_selection/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 379c976df69..379c976df69 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index fa3d0241998..fa3d0241998 100644 --- a/src/librustc_trait_selection/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index 0097097707f..0097097707f 100644 --- a/src/librustc_trait_selection/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs diff --git a/src/librustc_trait_selection/traits/codegen/mod.rs b/compiler/rustc_trait_selection/src/traits/codegen/mod.rs index dd7ea55cc10..dd7ea55cc10 100644 --- a/src/librustc_trait_selection/traits/codegen/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen/mod.rs diff --git a/src/librustc_trait_selection/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index b06cf4411d0..b06cf4411d0 100644 --- a/src/librustc_trait_selection/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs diff --git a/src/librustc_trait_selection/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 4d477886979..4d477886979 100644 --- a/src/librustc_trait_selection/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 28542d4b12e..28542d4b12e 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs diff --git a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index d2b9f84af33..d2b9f84af33 100644 --- a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 138293c9533..138293c9533 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index a5c6dc042ab..a5c6dc042ab 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs diff --git a/src/librustc_trait_selection/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 61567aeb57c..61567aeb57c 100644 --- a/src/librustc_trait_selection/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs diff --git a/src/librustc_trait_selection/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index fe406e88c52..fe406e88c52 100644 --- a/src/librustc_trait_selection/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index c003e4f8068..c003e4f8068 100644 --- a/src/librustc_trait_selection/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs diff --git a/src/librustc_trait_selection/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 75822eadb2a..75822eadb2a 100644 --- a/src/librustc_trait_selection/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs diff --git a/src/librustc_trait_selection/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c788e4f5c90..c788e4f5c90 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs diff --git a/src/librustc_trait_selection/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index d07c95270e0..d07c95270e0 100644 --- a/src/librustc_trait_selection/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs diff --git a/src/librustc_trait_selection/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 0569f6217da..0569f6217da 100644 --- a/src/librustc_trait_selection/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs diff --git a/src/librustc_trait_selection/traits/query/method_autoderef.rs b/compiler/rustc_trait_selection/src/traits/query/method_autoderef.rs index 3c0ebec9335..3c0ebec9335 100644 --- a/src/librustc_trait_selection/traits/query/method_autoderef.rs +++ b/compiler/rustc_trait_selection/src/traits/query/method_autoderef.rs diff --git a/src/librustc_trait_selection/traits/query/mod.rs b/compiler/rustc_trait_selection/src/traits/query/mod.rs index 01f4f09e238..01f4f09e238 100644 --- a/src/librustc_trait_selection/traits/query/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/mod.rs diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 93652329305..93652329305 100644 --- a/src/librustc_trait_selection/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs diff --git a/src/librustc_trait_selection/traits/query/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs index a42409515db..a42409515db 100644 --- a/src/librustc_trait_selection/traits/query/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/outlives_bounds.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index 86b015767f0..86b015767f0 100644 --- a/src/librustc_trait_selection/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 915e8ae4a7a..915e8ae4a7a 100644 --- a/src/librustc_trait_selection/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/eq.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs index 490114aacd1..490114aacd1 100644 --- a/src/librustc_trait_selection/traits/query/type_op/eq.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index cf7f0a553c7..cf7f0a553c7 100644 --- a/src/librustc_trait_selection/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index ed6c6d0cc0a..ed6c6d0cc0a 100644 --- a/src/librustc_trait_selection/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 729b66ac21c..729b66ac21c 100644 --- a/src/librustc_trait_selection/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index 5a27e57860e..5a27e57860e 100644 --- a/src/librustc_trait_selection/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 93ddcb68554..93ddcb68554 100644 --- a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs diff --git a/src/librustc_trait_selection/traits/query/type_op/subtype.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs index 57290b66914..57290b66914 100644 --- a/src/librustc_trait_selection/traits/query/type_op/subtype.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 1d5441b8eff..1d5441b8eff 100644 --- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3d6eb845136..3d6eb845136 100644 --- a/src/librustc_trait_selection/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 82f476b463d..82f476b463d 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 4d81a3baa0e..4d81a3baa0e 100644 --- a/src/librustc_trait_selection/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs diff --git a/src/librustc_trait_selection/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 56b8354d68c..56b8354d68c 100644 --- a/src/librustc_trait_selection/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 78186a5e8a5..78186a5e8a5 100644 --- a/src/librustc_trait_selection/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs diff --git a/src/librustc_trait_selection/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index f626bb0b7e3..f626bb0b7e3 100644 --- a/src/librustc_trait_selection/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs diff --git a/src/librustc_trait_selection/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 0ac3c6ffe62..0ac3c6ffe62 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml new file mode 100644 index 00000000000..2d63fc51220 --- /dev/null +++ b/compiler/rustc_traits/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_traits" +version = "0.0.0" +edition = "2018" + +[dependencies] +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +chalk-ir = "0.14.0" +chalk-solve = "0.14.0" +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_infer = { path = "../rustc_infer" } +rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/src/librustc_traits/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 4c8be8eb610..4c8be8eb610 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs diff --git a/src/librustc_traits/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index a043fa3f4c8..a043fa3f4c8 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs diff --git a/src/librustc_traits/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index f18b4ca65f6..f18b4ca65f6 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs diff --git a/src/librustc_traits/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index ce00060b9b1..ce00060b9b1 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs diff --git a/src/librustc_traits/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index 2404b7ff4b5..2404b7ff4b5 100644 --- a/src/librustc_traits/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index de3096eac9b..de3096eac9b 100644 --- a/src/librustc_traits/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs diff --git a/src/librustc_traits/lib.rs b/compiler/rustc_traits/src/lib.rs index 6fea4732dda..6fea4732dda 100644 --- a/src/librustc_traits/lib.rs +++ b/compiler/rustc_traits/src/lib.rs diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 83aee31a39f..83aee31a39f 100644 --- a/src/librustc_traits/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs diff --git a/src/librustc_traits/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index a8e376838e2..a8e376838e2 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs diff --git a/src/librustc_traits/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 139ed6dcd35..139ed6dcd35 100644 --- a/src/librustc_traits/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs diff --git a/compiler/rustc_ty/Cargo.toml b/compiler/rustc_ty/Cargo.toml new file mode 100644 index 00000000000..acb011b2dc0 --- /dev/null +++ b/compiler/rustc_ty/Cargo.toml @@ -0,0 +1,17 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ty" +version = "0.0.0" +edition = "2018" + +[dependencies] +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_infer = { path = "../rustc_infer" } +rustc_span = { path = "../rustc_span" } +rustc_session = { path = "../rustc_session" } +rustc_target = { path = "../rustc_target" } +rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/src/librustc_ty/common_traits.rs b/compiler/rustc_ty/src/common_traits.rs index 24ba0717866..24ba0717866 100644 --- a/src/librustc_ty/common_traits.rs +++ b/compiler/rustc_ty/src/common_traits.rs diff --git a/src/librustc_ty/instance.rs b/compiler/rustc_ty/src/instance.rs index d0bd88af1ff..d0bd88af1ff 100644 --- a/src/librustc_ty/instance.rs +++ b/compiler/rustc_ty/src/instance.rs diff --git a/src/librustc_ty/lib.rs b/compiler/rustc_ty/src/lib.rs index 6e9042d1ba7..6e9042d1ba7 100644 --- a/src/librustc_ty/lib.rs +++ b/compiler/rustc_ty/src/lib.rs diff --git a/src/librustc_ty/needs_drop.rs b/compiler/rustc_ty/src/needs_drop.rs index c4af95205fe..c4af95205fe 100644 --- a/src/librustc_ty/needs_drop.rs +++ b/compiler/rustc_ty/src/needs_drop.rs diff --git a/src/librustc_ty/ty.rs b/compiler/rustc_ty/src/ty.rs index 0f1dee7e2e0..0f1dee7e2e0 100644 --- a/src/librustc_ty/ty.rs +++ b/compiler/rustc_ty/src/ty.rs diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml new file mode 100644 index 00000000000..0a6bfaef431 --- /dev/null +++ b/compiler/rustc_typeck/Cargo.toml @@ -0,0 +1,27 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_typeck" +version = "0.0.0" +edition = "2018" + +[lib] +test = false +doctest = false + +[dependencies] +rustc_arena = { path = "../rustc_arena" } +tracing = "0.1" +rustc_middle = { path = "../rustc_middle" } +rustc_attr = { path = "../rustc_attr" } +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_target = { path = "../rustc_target" } +rustc_session = { path = "../rustc_session" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } +rustc_ast = { path = "../rustc_ast" } +rustc_span = { path = "../rustc_span" } +rustc_index = { path = "../rustc_index" } +rustc_infer = { path = "../rustc_infer" } +rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/src/librustc_typeck/README.md b/compiler/rustc_typeck/README.md index b61dbd8c964..b61dbd8c964 100644 --- a/src/librustc_typeck/README.md +++ b/compiler/rustc_typeck/README.md diff --git a/src/librustc_typeck/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 685243f54cb..685243f54cb 100644 --- a/src/librustc_typeck/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs diff --git a/src/librustc_typeck/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 84dab6de958..84dab6de958 100644 --- a/src/librustc_typeck/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs diff --git a/src/librustc_typeck/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 80dd26e9154..80dd26e9154 100644 --- a/src/librustc_typeck/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs diff --git a/src/librustc_typeck/bounds.rs b/compiler/rustc_typeck/src/bounds.rs index 63295f5faac..63295f5faac 100644 --- a/src/librustc_typeck/bounds.rs +++ b/compiler/rustc_typeck/src/bounds.rs diff --git a/src/librustc_typeck/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index afd4413069e..afd4413069e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs diff --git a/src/librustc_typeck/check/autoderef.rs b/compiler/rustc_typeck/src/check/autoderef.rs index 97d2b3e5a8e..97d2b3e5a8e 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/compiler/rustc_typeck/src/check/autoderef.rs diff --git a/src/librustc_typeck/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 4ba64035ca4..4ba64035ca4 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs diff --git a/src/librustc_typeck/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index e41314e8ab0..e41314e8ab0 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs diff --git a/src/librustc_typeck/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 97f7e4537ce..97f7e4537ce 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs diff --git a/src/librustc_typeck/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index f0802c45ae0..f0802c45ae0 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs diff --git a/src/librustc_typeck/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 7adcd7b472e..7adcd7b472e 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs diff --git a/src/librustc_typeck/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 5dc5480c335..5dc5480c335 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs diff --git a/src/librustc_typeck/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 434886538fb..434886538fb 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs diff --git a/src/librustc_typeck/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 1573fb96791..cc8a6953f13 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -764,9 +764,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rhs: &'tcx hir::Expr<'tcx>, span: &Span, ) -> Ty<'tcx> { - let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); - let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs)); - let expected_ty = expected.coercion_target_type(self, expr.span); if expected_ty == self.tcx.types.bool { // The expected type is `bool` but this will result in `()` so we can reasonably @@ -774,20 +771,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The likely cause of this is `if foo = bar { .. }`. let actual_ty = self.tcx.mk_unit(); let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap(); - let msg = "try comparing for equality"; - let left = self.tcx.sess.source_map().span_to_snippet(lhs.span); - let right = self.tcx.sess.source_map().span_to_snippet(rhs.span); - if let (Ok(left), Ok(right)) = (left, right) { - let help = format!("{} == {}", left, right); - err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect); + let lhs_ty = self.check_expr(&lhs); + let rhs_ty = self.check_expr(&rhs); + if self.can_coerce(lhs_ty, rhs_ty) { + if !lhs.is_syntactic_place_expr() { + // Do not suggest `if let x = y` as `==` is way more likely to be the intention. + if let hir::Node::Expr(hir::Expr { + kind: ExprKind::Match(_, _, hir::MatchSource::IfDesugar { .. }), + .. + }) = self.tcx.hir().get( + self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)), + ) { + // Likely `if let` intended. + err.span_suggestion_verbose( + expr.span.shrink_to_lo(), + "you might have meant to use pattern matching", + "let ".to_string(), + Applicability::MaybeIncorrect, + ); + } + } + err.span_suggestion_verbose( + *span, + "you might have meant to compare for equality", + "==".to_string(), + Applicability::MaybeIncorrect, + ); } else { - err.help(msg); + // Do this to cause extra errors about the assignment. + let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); + let _ = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs)); } - err.emit(); - } else { - self.check_lhs_assignable(lhs, "E0070", span); + + if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() { + // We already emitted an `if let` suggestion due to an identifier not found. + err.delay_as_bug(); + } else { + err.emit(); + } + return self.tcx.ty_error(); } + self.check_lhs_assignable(lhs, "E0070", span); + + let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); + let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs)); + self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized); if lhs_ty.references_error() || rhs_ty.references_error() { diff --git a/src/librustc_typeck/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 93fdf93e9e3..93fdf93e9e3 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs diff --git a/src/librustc_typeck/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 47cea8649ef..47cea8649ef 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs diff --git a/src/librustc_typeck/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 41e37ee9752..41e37ee9752 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs diff --git a/src/librustc_typeck/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index c9a4df0317a..c9a4df0317a 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs diff --git a/src/librustc_typeck/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 7ac6681be1a..7ac6681be1a 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs diff --git a/src/librustc_typeck/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 5cae66bc5da..5cae66bc5da 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs diff --git a/src/librustc_typeck/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 031d48f8a60..031d48f8a60 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs diff --git a/src/librustc_typeck/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 66fb01a54f5..66fb01a54f5 100644 --- a/src/librustc_typeck/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs diff --git a/src/librustc_typeck/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index d1864ee2b35..d1864ee2b35 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs diff --git a/src/librustc_typeck/check/place_op.rs b/compiler/rustc_typeck/src/check/place_op.rs index 4bef9aecd2e..4bef9aecd2e 100644 --- a/src/librustc_typeck/check/place_op.rs +++ b/compiler/rustc_typeck/src/check/place_op.rs diff --git a/src/librustc_typeck/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index 484961dbdb8..484961dbdb8 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs diff --git a/src/librustc_typeck/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 9bb84c07868..9bb84c07868 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs diff --git a/src/librustc_typeck/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 9c692edaa7f..9c692edaa7f 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs diff --git a/src/librustc_typeck/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 67f67e64dd4..67f67e64dd4 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs diff --git a/src/librustc_typeck/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs index 4fda8932e21..4fda8932e21 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/compiler/rustc_typeck/src/check_unused.rs diff --git a/src/librustc_typeck/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index 0d3cac7f7f3..0d3cac7f7f3 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/compiler/rustc_typeck/src/coherence/builtin.rs diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index 859d510dcbe..859d510dcbe 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs index be77d049cae..be77d049cae 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs diff --git a/src/librustc_typeck/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs index 1483244717b..1483244717b 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/compiler/rustc_typeck/src/coherence/mod.rs diff --git a/src/librustc_typeck/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 71469770f2a..71469770f2a 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs diff --git a/src/librustc_typeck/coherence/unsafety.rs b/compiler/rustc_typeck/src/coherence/unsafety.rs index b281092ea63..b281092ea63 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/compiler/rustc_typeck/src/coherence/unsafety.rs diff --git a/src/librustc_typeck/collect.rs b/compiler/rustc_typeck/src/collect.rs index 7a3f7ec56a2..7a3f7ec56a2 100644 --- a/src/librustc_typeck/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs diff --git a/src/librustc_typeck/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 70ed92c5614..70ed92c5614 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs diff --git a/src/librustc_typeck/constrained_generic_params.rs b/compiler/rustc_typeck/src/constrained_generic_params.rs index 7c80315ee19..7c80315ee19 100644 --- a/src/librustc_typeck/constrained_generic_params.rs +++ b/compiler/rustc_typeck/src/constrained_generic_params.rs diff --git a/src/librustc_typeck/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index e774f2d095d..e774f2d095d 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs diff --git a/src/librustc_typeck/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index 891e482b431..891e482b431 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 3746e5778aa..3746e5778aa 100644 --- a/src/librustc_typeck/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs diff --git a/src/librustc_typeck/lib.rs b/compiler/rustc_typeck/src/lib.rs index 62f92fe7ffa..62f92fe7ffa 100644 --- a/src/librustc_typeck/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs diff --git a/src/librustc_typeck/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs index 8a6fe620af7..8a6fe620af7 100644 --- a/src/librustc_typeck/mem_categorization.rs +++ b/compiler/rustc_typeck/src/mem_categorization.rs diff --git a/src/librustc_typeck/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs index 135960a4c11..135960a4c11 100644 --- a/src/librustc_typeck/outlives/explicit.rs +++ b/compiler/rustc_typeck/src/outlives/explicit.rs diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 762d4216f70..762d4216f70 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs diff --git a/src/librustc_typeck/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index 94926f480e2..94926f480e2 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs diff --git a/src/librustc_typeck/outlives/test.rs b/compiler/rustc_typeck/src/outlives/test.rs index abe9319d71c..abe9319d71c 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/compiler/rustc_typeck/src/outlives/test.rs diff --git a/src/librustc_typeck/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs index 8b069678796..8b069678796 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/compiler/rustc_typeck/src/outlives/utils.rs diff --git a/src/librustc_typeck/structured_errors.rs b/compiler/rustc_typeck/src/structured_errors.rs index 83125a3e2fe..83125a3e2fe 100644 --- a/src/librustc_typeck/structured_errors.rs +++ b/compiler/rustc_typeck/src/structured_errors.rs diff --git a/src/librustc_typeck/variance/constraints.rs b/compiler/rustc_typeck/src/variance/constraints.rs index 535530a2ed4..535530a2ed4 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/compiler/rustc_typeck/src/variance/constraints.rs diff --git a/src/librustc_typeck/variance/mod.rs b/compiler/rustc_typeck/src/variance/mod.rs index a893f69c48a..a893f69c48a 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/compiler/rustc_typeck/src/variance/mod.rs diff --git a/src/librustc_typeck/variance/solve.rs b/compiler/rustc_typeck/src/variance/solve.rs index 7402117a7eb..7402117a7eb 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/compiler/rustc_typeck/src/variance/solve.rs diff --git a/src/librustc_typeck/variance/terms.rs b/compiler/rustc_typeck/src/variance/terms.rs index f61a783de69..f61a783de69 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/compiler/rustc_typeck/src/variance/terms.rs diff --git a/src/librustc_typeck/variance/test.rs b/compiler/rustc_typeck/src/variance/test.rs index 1aab89310c6..1aab89310c6 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/compiler/rustc_typeck/src/variance/test.rs diff --git a/src/librustc_typeck/variance/xform.rs b/compiler/rustc_typeck/src/variance/xform.rs index 027f0859fcd..027f0859fcd 100644 --- a/src/librustc_typeck/variance/xform.rs +++ b/compiler/rustc_typeck/src/variance/xform.rs diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 51c233a21f1..e7260f3956c 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -217,7 +217,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> { /// assert!(!bull.is_borrowed()); /// ``` #[unstable(feature = "cow_is_borrowed", issue = "65143")] - pub fn is_borrowed(&self) -> bool { + pub const fn is_borrowed(&self) -> bool { match *self { Borrowed(_) => true, Owned(_) => false, @@ -239,7 +239,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> { /// assert!(!bull.is_owned()); /// ``` #[unstable(feature = "cow_is_borrowed", issue = "65143")] - pub fn is_owned(&self) -> bool { + pub const fn is_owned(&self) -> bool { !self.is_borrowed() } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 05211e2037b..5c8c2c5a5a8 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -217,7 +217,7 @@ impl<T> Box<T> { /// assert_eq!(*zero, 0) /// ``` /// - /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> { let layout = alloc::Layout::new::<mem::MaybeUninit<T>>(); @@ -289,7 +289,7 @@ impl<T> Box<[T]> { /// assert_eq!(*values, [0, 0, 0]) /// ``` /// - /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } @@ -307,7 +307,7 @@ impl<T> Box<mem::MaybeUninit<T>> { /// Calling this when the content is not yet fully initialized /// causes immediate undefined behavior. /// - /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init /// /// # Examples /// @@ -343,7 +343,7 @@ impl<T> Box<[mem::MaybeUninit<T>]> { /// Calling this when the content is not yet fully initialized /// causes immediate undefined behavior. /// - /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init /// /// # Examples /// diff --git a/library/alloc/src/collections/vec_deque.rs b/library/alloc/src/collections/vec_deque.rs index d3c6d493d6d..52b9f73ba88 100644 --- a/library/alloc/src/collections/vec_deque.rs +++ b/library/alloc/src/collections/vec_deque.rs @@ -47,10 +47,17 @@ const MAXIMUM_ZST_CAPACITY: usize = 1 << (64 - 1); // Largest possible power of /// push onto the back in this manner, and iterating over `VecDeque` goes front /// to back. /// +/// Since `VecDeque` is a ring buffer, its elements are not necessarily contiguous +/// in memory. If you want to access the elements as a single slice, such as for +/// efficient sorting, you can use [`make_contiguous`]. It rotates the `VecDeque` +/// so that its elements do not wrap, and returns a mutable slice to the +/// now-contiguous element sequence. +/// /// [`push_back`]: #method.push_back /// [`pop_front`]: #method.pop_front /// [`extend`]: #method.extend /// [`append`]: #method.append +/// [`make_contiguous`]: #method.make_contiguous #[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_type")] #[stable(feature = "rust1", since = "1.0.0")] pub struct VecDeque<T> { @@ -678,7 +685,7 @@ impl<T> VecDeque<T> { } /// Tries to reserve the minimum capacity for exactly `additional` more elements to - /// be inserted in the given `VecDeque<T>`. After calling `reserve_exact`, + /// be inserted in the given `VecDeque<T>`. After calling `try_reserve_exact`, /// capacity will be greater than or equal to `self.len() + additional`. /// Does nothing if the capacity is already sufficient. /// @@ -720,7 +727,7 @@ impl<T> VecDeque<T> { /// Tries to reserve capacity for at least `additional` more elements to be inserted /// in the given `VecDeque<T>`. The collection may reserve more space to avoid - /// frequent reallocations. After calling `reserve`, capacity will be + /// frequent reallocations. After calling `try_reserve`, capacity will be /// greater than or equal to `self.len() + additional`. Does nothing if /// capacity is already sufficient. /// @@ -2188,8 +2195,6 @@ impl<T> VecDeque<T> { /// Sorting the content of a deque. /// /// ``` - /// #![feature(deque_make_contiguous)] - /// /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::with_capacity(15); @@ -2210,8 +2215,6 @@ impl<T> VecDeque<T> { /// Getting immutable access to the contiguous slice. /// /// ```rust - /// #![feature(deque_make_contiguous)] - /// /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); @@ -2228,7 +2231,7 @@ impl<T> VecDeque<T> { /// assert_eq!(slice, &[3, 2, 1] as &[_]); /// } /// ``` - #[unstable(feature = "deque_make_contiguous", issue = "70929")] + #[stable(feature = "deque_make_contiguous", since = "1.48.0")] pub fn make_contiguous(&mut self) -> &mut [T] { if self.is_contiguous() { let tail = self.tail; diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 1046397f4be..2f0a374015a 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -376,7 +376,7 @@ impl<T> Rc<T> { /// assert_eq!(*zero, 0) /// ``` /// - /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> { unsafe { @@ -484,7 +484,7 @@ impl<T> Rc<[T]> { /// assert_eq!(*values, [0, 0, 0]) /// ``` /// - /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed + /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> { unsafe { @@ -511,7 +511,7 @@ impl<T> Rc<mem::MaybeUninit<T>> { /// Calling this when the content is not yet fully initialized /// causes immediate undefined behavior. /// - /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init /// /// # Examples /// @@ -550,7 +550,7 @@ impl<T> Rc<[mem::MaybeUninit<T>]> { /// Calling this when the content is not yet fully initialized /// causes immediate undefined behavior. /// - /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init + /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init /// /// # Examples /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 73d2fe74826..6a240fbb42a 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -111,7 +111,7 @@ macro_rules! acquire { /// /// # Cloning references /// -/// Creating a new reference from an existing reference counted pointer is done using the +/// Creating a new reference from an existing reference-counted pointer is done using the /// `Clone` trait implemented for [`Arc<T>`][Arc] and [`Weak<T>`][Weak]. /// /// ``` @@ -152,7 +152,7 @@ macro_rules! acquire { /// [upgrade]: Weak::upgrade /// [`RefCell<T>`]: core::cell::RefCell /// [`std::sync`]: ../../std/sync/index.html -/// [`Arc::clone(&from)`]: #method.clone +/// [`Arc::clone(&from)`]: Arc::clone /// /// # Examples /// @@ -201,7 +201,7 @@ macro_rules! acquire { /// See the [`rc` documentation][rc_examples] for more examples of reference /// counting in general. /// -/// [rc_examples]: ../../std/rc/index.html#examples +/// [rc_examples]: crate::rc#examples #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc<T: ?Sized> { diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 61e1245f073..27eefb05842 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -114,8 +114,9 @@ use crate::raw_vec::RawVec; /// assert_eq!(vec, [0, 0, 0, 0, 0]); /// /// // The following is equivalent, but potentially slower: -/// let mut vec1 = Vec::with_capacity(5); -/// vec1.resize(5, 0); +/// let mut vec = Vec::with_capacity(5); +/// vec.resize(5, 0); +/// assert_eq!(vec, [0, 0, 0, 0, 0]); /// ``` /// /// Use a `Vec<T>` as an efficient stack: @@ -522,7 +523,7 @@ impl<T> Vec<T> { /// Tries to reserve capacity for at least `additional` more elements to be inserted /// in the given `Vec<T>`. The collection may reserve more space to avoid - /// frequent reallocations. After calling `reserve`, capacity will be + /// frequent reallocations. After calling `try_reserve`, capacity will be /// greater than or equal to `self.len() + additional`. Does nothing if /// capacity is already sufficient. /// @@ -558,7 +559,7 @@ impl<T> Vec<T> { } /// Tries to reserves the minimum capacity for exactly `additional` more elements to - /// be inserted in the given `Vec<T>`. After calling `reserve_exact`, + /// be inserted in the given `Vec<T>`. After calling `try_reserve_exact`, /// capacity will be greater than or equal to `self.len() + additional`. /// Does nothing if the capacity is already sufficient. /// @@ -581,7 +582,7 @@ impl<T> Vec<T> { /// let mut output = Vec::new(); /// /// // Pre-reserve the memory, exiting if we can't - /// output.try_reserve(data.len())?; + /// output.try_reserve_exact(data.len())?; /// /// // Now we know this can't OOM in the middle of our complex work /// output.extend(data.iter().map(|&val| { @@ -1565,7 +1566,7 @@ impl<T: Clone> Vec<T> { /// This method requires `T` to implement [`Clone`], /// in order to be able to clone the passed value. /// If you need more flexibility (or want to rely on [`Default`] instead of - /// [`Clone`]), use [`resize_with`]. + /// [`Clone`]), use [`Vec::resize_with`]. /// /// # Examples /// @@ -1578,8 +1579,6 @@ impl<T: Clone> Vec<T> { /// vec.resize(2, 0); /// assert_eq!(vec, [1, 2]); /// ``` - /// - /// [`resize_with`]: Vec::resize_with #[stable(feature = "vec_resize", since = "1.5.0")] pub fn resize(&mut self, new_len: usize, value: T) { let len = self.len(); @@ -1609,7 +1608,7 @@ impl<T: Clone> Vec<T> { /// assert_eq!(vec, [1, 2, 3, 4]); /// ``` /// - /// [`extend`]: #method.extend + /// [`extend`]: Vec::extend #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] pub fn extend_from_slice(&mut self, other: &[T]) { self.spec_extend(other.iter()) @@ -3024,7 +3023,10 @@ impl<T> Drain<'_, T> { } } -/// An iterator produced by calling `drain_filter` on Vec. +/// An iterator which uses a closure to determine if an element should be removed. +/// +/// This struct is created by [`Vec::drain_filter`]. +/// See its documentation for more. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] #[derive(Debug)] pub struct DrainFilter<'a, T, F> diff --git a/library/core/benches/num/flt2dec/strategy/dragon.rs b/library/core/benches/num/flt2dec/strategy/dragon.rs index 4e1fd8bf753..319b9773e49 100644 --- a/library/core/benches/num/flt2dec/strategy/dragon.rs +++ b/library/core/benches/num/flt2dec/strategy/dragon.rs @@ -1,59 +1,76 @@ use super::super::*; use core::num::flt2dec::strategy::dragon::*; +use std::mem::MaybeUninit; use test::Bencher; #[bench] fn bench_small_shortest(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; MAX_SIG_DIGITS]; - b.iter(|| format_shortest(&decoded, &mut buf)); + let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS]; + b.iter(|| { + format_shortest(&decoded, &mut buf); + }); } #[bench] fn bench_big_shortest(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; MAX_SIG_DIGITS]; - b.iter(|| format_shortest(&decoded, &mut buf)); + let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS]; + b.iter(|| { + format_shortest(&decoded, &mut buf); + }); } #[bench] fn bench_small_exact_3(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; 3]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 3]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_big_exact_3(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; 3]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 3]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_small_exact_12(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; 12]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 12]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_big_exact_12(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; 12]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 12]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_small_exact_inf(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; 1024]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_big_exact_inf(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; 1024]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } diff --git a/library/core/benches/num/flt2dec/strategy/grisu.rs b/library/core/benches/num/flt2dec/strategy/grisu.rs index 77ca901a90a..76425731e1d 100644 --- a/library/core/benches/num/flt2dec/strategy/grisu.rs +++ b/library/core/benches/num/flt2dec/strategy/grisu.rs @@ -1,5 +1,6 @@ use super::super::*; use core::num::flt2dec::strategy::grisu::*; +use std::mem::MaybeUninit; use test::Bencher; pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded { @@ -12,55 +13,71 @@ pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded { #[bench] fn bench_small_shortest(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; MAX_SIG_DIGITS]; - b.iter(|| format_shortest(&decoded, &mut buf)); + let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS]; + b.iter(|| { + format_shortest(&decoded, &mut buf); + }); } #[bench] fn bench_big_shortest(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; MAX_SIG_DIGITS]; - b.iter(|| format_shortest(&decoded, &mut buf)); + let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS]; + b.iter(|| { + format_shortest(&decoded, &mut buf); + }); } #[bench] fn bench_small_exact_3(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; 3]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 3]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_big_exact_3(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; 3]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 3]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_small_exact_12(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; 12]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 12]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_big_exact_12(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; 12]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 12]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_small_exact_inf(b: &mut Bencher) { let decoded = decode_finite(3.141592f64); - let mut buf = [0; 1024]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } #[bench] fn bench_big_exact_inf(b: &mut Bencher) { let decoded = decode_finite(f64::MAX); - let mut buf = [0; 1024]; - b.iter(|| format_exact(&decoded, &mut buf, i16::MIN)); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(&decoded, &mut buf, i16::MIN); + }); } diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index f85be5584e3..f45c99c285c 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -422,4 +422,17 @@ impl<T, const N: usize> [T; N] { // and we just need to cast it to the correct type. unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) } } + + /// Returns a slice containing the entire array. Equivalent to `&s[..]`. + #[unstable(feature = "array_methods", issue = "76118")] + pub fn as_slice(&self) -> &[T] { + self + } + + /// Returns a mutable slice containing the entire array. Equivalent to + /// `&mut s[..]`. + #[unstable(feature = "array_methods", issue = "76118")] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self + } } diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 7784ec687ea..a953a3a4182 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -7,11 +7,9 @@ //! contain owned boxes or implement [`Drop`]), so the compiler considers //! them cheap and safe to copy. For other types copies must be made //! explicitly, by convention implementing the [`Clone`] trait and calling -//! the [`clone`][clone] method. +//! the [`clone`] method. //! -//! [`Clone`]: trait.Clone.html -//! [clone]: trait.Clone.html#tymethod.clone -//! [`Drop`]: ../../std/ops/trait.Drop.html +//! [`clone`]: Clone::clone //! //! Basic usage example: //! @@ -51,7 +49,9 @@ /// ## Derivable /// /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d -/// implementation of [`clone`] calls [`clone`] on each field. +/// implementation of [`Clone`] calls [`clone`] on each field. +/// +/// [`clone`]: Clone::clone /// /// For a generic struct, `#[derive]` implements `Clone` conditionally by adding bound `Clone` on /// generic parameters. @@ -74,9 +74,6 @@ /// An example is a generic struct holding a function pointer. In this case, the /// implementation of `Clone` cannot be `derive`d, but can be implemented as: /// -/// [`Copy`]: ../../std/marker/trait.Copy.html -/// [`clone`]: trait.Clone.html#tymethod.clone -/// /// ``` /// struct Generate<T>(fn() -> T); /// diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 5f10a2eb023..2bfeb49b5fa 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -31,13 +31,6 @@ //! `into` themselves and `from` themselves //! //! See each trait for usage examples. -//! -//! [`Into`]: trait.Into.html -//! [`From`]: trait.From.html -//! [`TryFrom`]: trait.TryFrom.html -//! [`TryInto`]: trait.TryInto.html -//! [`AsRef`]: trait.AsRef.html -//! [`AsMut`]: trait.AsMut.html #![stable(feature = "rust1", since = "1.0.0")] @@ -141,13 +134,11 @@ pub const fn identity<T>(x: T) -> T { /// want to accept all references that can be converted to [`&str`] as an argument. /// Since both [`String`] and [`&str`] implement `AsRef<str>` we can accept both as input argument. /// -/// [`Option<T>`]: ../../std/option/enum.Option.html -/// [`Result<T, E>`]: ../../std/result/enum.Result.html -/// [`Borrow`]: ../../std/borrow/trait.Borrow.html -/// [`Hash`]: ../../std/hash/trait.Hash.html -/// [`Eq`]: ../../std/cmp/trait.Eq.html -/// [`Ord`]: ../../std/cmp/trait.Ord.html -/// [`&str`]: ../../std/primitive.str.html +/// [`Option<T>`]: Option +/// [`Result<T, E>`]: Result +/// [`Borrow`]: crate::borrow::Borrow +/// [`Eq`]: crate::cmp::Eq +/// [`Ord`]: crate::cmp::Ord /// [`String`]: ../../std/string/struct.String.html /// /// ``` @@ -177,8 +168,8 @@ pub trait AsRef<T: ?Sized> { /// **Note: This trait must not fail**. If the conversion can fail, use a /// dedicated method which returns an [`Option<T>`] or a [`Result<T, E>`]. /// -/// [`Option<T>`]: ../../std/option/enum.Option.html -/// [`Result<T, E>`]: ../../std/result/enum.Result.html +/// [`Option<T>`]: Option +/// [`Result<T, E>`]: Result /// /// # Generic Implementations /// @@ -278,12 +269,9 @@ pub trait AsMut<T: ?Sized> { /// is_hello(s); /// ``` /// -/// [`TryInto`]: trait.TryInto.html -/// [`Option<T>`]: ../../std/option/enum.Option.html -/// [`Result<T, E>`]: ../../std/result/enum.Result.html +/// [`Option<T>`]: Option +/// [`Result<T, E>`]: Result /// [`String`]: ../../std/string/struct.String.html -/// [`From`]: trait.From.html -/// [`Into`]: trait.Into.html /// [`Vec`]: ../../std/vec/struct.Vec.html #[stable(feature = "rust1", since = "1.0.0")] pub trait Into<T>: Sized { @@ -370,12 +358,10 @@ pub trait Into<T>: Sized { /// } /// ``` /// -/// [`TryFrom`]: trait.TryFrom.html -/// [`Option<T>`]: ../../std/option/enum.Option.html -/// [`Result<T, E>`]: ../../std/result/enum.Result.html +/// [`Option<T>`]: Option +/// [`Result<T, E>`]: Result /// [`String`]: ../../std/string/struct.String.html -/// [`Into`]: trait.Into.html -/// [`from`]: trait.From.html#tymethod.from +/// [`from`]: From::from /// [book]: ../../book/ch09-00-error-handling.html #[rustc_diagnostic_item = "from_trait"] #[stable(feature = "rust1", since = "1.0.0")] @@ -404,9 +390,6 @@ pub trait From<T>: Sized { /// /// This suffers the same restrictions and reasoning as implementing /// [`Into`], see there for details. -/// -/// [`TryFrom`]: trait.TryFrom.html -/// [`Into`]: trait.Into.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryInto<T>: Sized { /// The type returned in the event of a conversion error. @@ -485,11 +468,9 @@ pub trait TryInto<T>: Sized { /// assert!(try_successful_smaller_number.is_ok()); /// ``` /// -/// [`try_from`]: trait.TryFrom.html#tymethod.try_from -/// [`TryInto`]: trait.TryInto.html -/// [`i32::MAX`]: ../../std/i32/constant.MAX.html +/// [`i32::MAX`]: crate::i32::MAX +/// [`try_from`]: TryFrom::try_from /// [`!`]: ../../std/primitive.never.html -/// [`Infallible`]: enum.Infallible.html #[stable(feature = "try_from", since = "1.34.0")] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. @@ -676,7 +657,6 @@ impl AsRef<str> for str { /// /// … and eventually deprecate `Infallible`. /// -/// /// However there is one case where `!` syntax can be used /// before `!` is stabilized as a full-fledged type: in the position of a function’s return type. /// Specifically, it is possible implementations for two different function pointer types: @@ -692,10 +672,6 @@ impl AsRef<str> for str { /// the two `impl`s will start to overlap /// and therefore will be disallowed by the language’s trait coherence rules. /// -/// [`Ok`]: ../result/enum.Result.html#variant.Ok -/// [`Result`]: ../result/enum.Result.html -/// [`TryFrom`]: trait.TryFrom.html -/// [`Into`]: trait.Into.html /// [never]: ../../std/primitive.never.html #[stable(feature = "convert_infallible", since = "1.34.0")] #[derive(Copy)] diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 52d8349bc9a..5908da477e1 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -14,25 +14,17 @@ fn float_to_decimal_common_exact<T>( where T: flt2dec::DecodableFloat, { - // SAFETY: Possible undefined behavior, see FIXME(#53491) - unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit(); - // FIXME(#53491): This is calling `get_mut` on an uninitialized - // `MaybeUninit` (here and elsewhere in this file). Revisit this once - // we decided whether that is valid or not. - // We can do this only because we are libstd and coupled to the compiler. - // (FWIW, using `freeze` would not be enough; `flt2dec::Part` is an enum!) - let formatted = flt2dec::to_exact_fixed_str( - flt2dec::strategy::grisu::format_exact, - *num, - sign, - precision, - buf.get_mut(), - parts.get_mut(), - ); - fmt.pad_formatted_parts(&formatted) - } + let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 + let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array(); + let formatted = flt2dec::to_exact_fixed_str( + flt2dec::strategy::grisu::format_exact, + *num, + sign, + precision, + &mut buf, + &mut parts, + ); + fmt.pad_formatted_parts(&formatted) } // Don't inline this so callers that call both this and the above won't wind @@ -47,22 +39,18 @@ fn float_to_decimal_common_shortest<T>( where T: flt2dec::DecodableFloat, { - // SAFETY: Possible undefined behavior, see FIXME(#53491) - unsafe { - // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); - let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 4]>::uninit(); - // FIXME(#53491) - let formatted = flt2dec::to_shortest_str( - flt2dec::strategy::grisu::format_shortest, - *num, - sign, - precision, - buf.get_mut(), - parts.get_mut(), - ); - fmt.pad_formatted_parts(&formatted) - } + // enough for f32 and f64 + let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); + let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array(); + let formatted = flt2dec::to_shortest_str( + flt2dec::strategy::grisu::format_shortest, + *num, + sign, + precision, + &mut buf, + &mut parts, + ); + fmt.pad_formatted_parts(&formatted) } // Common code of floating point Debug and Display. @@ -103,22 +91,18 @@ fn float_to_exponential_common_exact<T>( where T: flt2dec::DecodableFloat, { - // SAFETY: Possible undefined behavior, see FIXME(#53491) - unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit(); - // FIXME(#53491) - let formatted = flt2dec::to_exact_exp_str( - flt2dec::strategy::grisu::format_exact, - *num, - sign, - precision, - upper, - buf.get_mut(), - parts.get_mut(), - ); - fmt.pad_formatted_parts(&formatted) - } + let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 + let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array(); + let formatted = flt2dec::to_exact_exp_str( + flt2dec::strategy::grisu::format_exact, + *num, + sign, + precision, + upper, + &mut buf, + &mut parts, + ); + fmt.pad_formatted_parts(&formatted) } // Don't inline this so callers that call both this and the above won't wind @@ -133,23 +117,19 @@ fn float_to_exponential_common_shortest<T>( where T: flt2dec::DecodableFloat, { - // SAFETY: Possible undefined behavior, see FIXME(#53491) - unsafe { - // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); - let mut parts = MaybeUninit::<[flt2dec::Part<'_>; 6]>::uninit(); - // FIXME(#53491) - let formatted = flt2dec::to_shortest_exp_str( - flt2dec::strategy::grisu::format_shortest, - *num, - sign, - (0, 0), - upper, - buf.get_mut(), - parts.get_mut(), - ); - fmt.pad_formatted_parts(&formatted) - } + // enough for f32 and f64 + let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); + let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array(); + let formatted = flt2dec::to_shortest_exp_str( + flt2dec::strategy::grisu::format_shortest, + *num, + sign, + (0, 0), + upper, + &mut buf, + &mut parts, + ); + fmt.pad_formatted_parts(&formatted) } // Common code of floating point LowerExp and UpperExp. diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 9fcd137e1a6..f32c3963abe 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1,9 +1,9 @@ use crate::cmp; use crate::fmt; use crate::intrinsics; -use crate::ops::{Add, AddAssign, Try}; +use crate::ops::{Add, AddAssign, ControlFlow, Try}; -use super::{from_fn, LoopState}; +use super::from_fn; use super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen}; mod chain; @@ -1164,10 +1164,10 @@ where #[inline] fn find<T, B>( f: &mut impl FnMut(T) -> Option<B>, - ) -> impl FnMut((), T) -> LoopState<(), B> + '_ { + ) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ { move |(), x| match f(x) { - Some(x) => LoopState::Break(x), - None => LoopState::Continue(()), + Some(x) => ControlFlow::Break(x), + None => ControlFlow::Continue(()), } } @@ -1864,13 +1864,13 @@ where flag: &'a mut bool, p: &'a mut impl FnMut(&T) -> bool, mut fold: impl FnMut(Acc, T) -> R + 'a, - ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a { move |acc, x| { if p(&x) { - LoopState::from_try(fold(acc, x)) + ControlFlow::from_try(fold(acc, x)) } else { *flag = true; - LoopState::Break(Try::from_ok(acc)) + ControlFlow::Break(Try::from_ok(acc)) } } } @@ -1963,8 +1963,8 @@ where { let Self { iter, predicate } = self; iter.try_fold(init, |acc, x| match predicate(x) { - Some(item) => LoopState::from_try(fold(acc, item)), - None => LoopState::Break(Try::from_ok(acc)), + Some(item) => ControlFlow::from_try(fold(acc, item)), + None => ControlFlow::Break(Try::from_ok(acc)), }) .into_try() } @@ -2135,11 +2135,11 @@ where fn check<T, Acc, R: Try<Ok = Acc>>( mut n: usize, mut fold: impl FnMut(Acc, T) -> R, - ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> { + ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> { move |acc, x| { n -= 1; let r = fold(acc, x); - if n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) } + if n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) } } } @@ -2246,11 +2246,11 @@ where fn check<'a, T, Acc, R: Try<Ok = Acc>>( n: &'a mut usize, mut fold: impl FnMut(Acc, T) -> R + 'a, - ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a { move |acc, x| { *n -= 1; let r = fold(acc, x); - if *n == 0 { LoopState::Break(r) } else { LoopState::from_try(r) } + if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) } } } @@ -2414,10 +2414,10 @@ where state: &'a mut St, f: &'a mut impl FnMut(&mut St, T) -> Option<B>, mut fold: impl FnMut(Acc, B) -> R + 'a, - ) -> impl FnMut(Acc, T) -> LoopState<Acc, R> + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a { move |acc, x| match f(state, x) { - None => LoopState::Break(Try::from_ok(acc)), - Some(x) => LoopState::from_try(fold(acc, x)), + None => ControlFlow::Break(Try::from_ok(acc)), + Some(x) => ControlFlow::from_try(fold(acc, x)), } } @@ -2638,10 +2638,10 @@ where let error = &mut *self.error; self.iter .try_fold(init, |acc, x| match x { - Ok(x) => LoopState::from_try(f(acc, x)), + Ok(x) => ControlFlow::from_try(f(acc, x)), Err(e) => { *error = Err(e); - LoopState::Break(Try::from_ok(acc)) + ControlFlow::Break(Try::from_ok(acc)) } }) .into_try() diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index 9b528cdbe30..bab8dda2915 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -54,8 +54,7 @@ //! below for more details. //! //! [`Some(Item)`]: Some -//! [`Iterator`]: trait.Iterator.html -//! [`next`]: trait.Iterator.html#tymethod.next +//! [`next`]: Iterator::next //! [`TryIter`]: ../../std/sync/mpsc/struct.TryIter.html //! //! # The three forms of iteration @@ -136,7 +135,7 @@ //! methods like `nth` and `fold` if an iterator can compute them more efficiently without calling //! `next`. //! -//! # for Loops and IntoIterator +//! # `for` loops and `IntoIterator` //! //! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic //! example of `for`: @@ -159,8 +158,7 @@ //! Let's take a look at that `for` loop again, and what the compiler converts //! it into: //! -//! [`IntoIterator`]: trait.IntoIterator.html -//! [`into_iter`]: trait.IntoIterator.html#tymethod.into_iter +//! [`into_iter`]: IntoIterator::into_iter //! //! ``` //! let values = vec![1, 2, 3, 4, 5]; @@ -222,9 +220,9 @@ //! across versions of Rust, so you should avoid relying on the exact values //! returned by an iterator which panicked. //! -//! [`map`]: trait.Iterator.html#method.map -//! [`take`]: trait.Iterator.html#method.take -//! [`filter`]: trait.Iterator.html#method.filter +//! [`map`]: Iterator::map +//! [`take`]: Iterator::take +//! [`filter`]: Iterator::filter //! //! # Laziness //! @@ -261,13 +259,13 @@ //! } //! ``` //! -//! [`map`]: trait.Iterator.html#method.map -//! [`for_each`]: trait.Iterator.html#method.for_each +//! [`map`]: Iterator::map +//! [`for_each`]: Iterator::for_each //! //! Another common way to evaluate an iterator is to use the [`collect`] //! method to produce a new collection. //! -//! [`collect`]: trait.Iterator.html#method.collect +//! [`collect`]: Iterator::collect //! //! # Infinity //! @@ -305,13 +303,11 @@ //! println!("The smallest number one is {}.", least); //! ``` //! -//! [`take`]: trait.Iterator.html#method.take -//! [`min`]: trait.Iterator.html#method.min +//! [`take`]: Iterator::take +//! [`min`]: Iterator::min #![stable(feature = "rust1", since = "1.0.0")] -use crate::ops::Try; - #[stable(feature = "rust1", since = "1.0.0")] pub use self::traits::Iterator; @@ -369,57 +365,3 @@ mod adapters; mod range; mod sources; mod traits; - -/// Used to make try_fold closures more like normal loops -#[derive(PartialEq)] -enum LoopState<C, B> { - Continue(C), - Break(B), -} - -impl<C, B> Try for LoopState<C, B> { - type Ok = C; - type Error = B; - #[inline] - fn into_result(self) -> Result<Self::Ok, Self::Error> { - match self { - LoopState::Continue(y) => Ok(y), - LoopState::Break(x) => Err(x), - } - } - #[inline] - fn from_error(v: Self::Error) -> Self { - LoopState::Break(v) - } - #[inline] - fn from_ok(v: Self::Ok) -> Self { - LoopState::Continue(v) - } -} - -impl<C, B> LoopState<C, B> { - #[inline] - fn break_value(self) -> Option<B> { - match self { - LoopState::Continue(..) => None, - LoopState::Break(x) => Some(x), - } - } -} - -impl<R: Try> LoopState<R::Ok, R> { - #[inline] - fn from_try(r: R) -> Self { - match Try::into_result(r) { - Ok(v) => LoopState::Continue(v), - Err(v) => LoopState::Break(Try::from_error(v)), - } - } - #[inline] - fn into_try(self) -> R { - match self { - LoopState::Continue(v) => Try::from_ok(v), - LoopState::Break(v) => v, - } - } -} diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 323fdbb45f3..f50807116bd 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -1,5 +1,4 @@ -use crate::iter::LoopState; -use crate::ops::Try; +use crate::ops::{ControlFlow, Try}; /// An iterator able to yield elements from both ends. /// @@ -309,9 +308,9 @@ pub trait DoubleEndedIterator: Iterator { #[inline] fn check<T>( mut predicate: impl FnMut(&T) -> bool, - ) -> impl FnMut((), T) -> LoopState<(), T> { + ) -> impl FnMut((), T) -> ControlFlow<(), T> { move |(), x| { - if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) } + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index a1d11b597a1..46ef12cd938 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3,9 +3,8 @@ // can't split that into multiple files. use crate::cmp::{self, Ordering}; -use crate::ops::{Add, Try}; +use crate::ops::{Add, ControlFlow, Try}; -use super::super::LoopState; use super::super::TrustedRandomAccess; use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse}; use super::super::{FlatMap, Flatten}; @@ -22,8 +21,8 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. /// -/// [module-level documentation]: index.html -/// [impl]: index.html#implementing-iterator +/// [module-level documentation]: crate::iter +/// [impl]: crate::iter#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( on( @@ -212,7 +211,7 @@ pub trait Iterator { /// returning the number of times it saw [`Some`]. Note that [`next`] has to be /// called at least once even if the iterator does not have any elements. /// - /// [`next`]: #tymethod.next + /// [`next`]: Iterator::next /// /// # Overflow Behavior /// @@ -449,9 +448,7 @@ pub trait Iterator { /// } /// ``` /// - /// [`once`]: fn.once.html - /// [`Iterator`]: trait.Iterator.html - /// [`IntoIterator`]: trait.IntoIterator.html + /// [`once`]: crate::iter::once /// [`OsStr`]: ../../std/ffi/struct.OsStr.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -496,9 +493,6 @@ pub trait Iterator { /// [`Iterator`] itself. For example, slices (`&[T]`) implement /// [`IntoIterator`], and so can be passed to `zip()` directly: /// - /// [`IntoIterator`]: trait.IntoIterator.html - /// [`Iterator`]: trait.Iterator.html - /// /// ``` /// let s1 = &[1, 2, 3]; /// let s2 = &[4, 5, 6]; @@ -530,8 +524,8 @@ pub trait Iterator { /// assert_eq!((2, 'o'), zipper[2]); /// ``` /// - /// [`enumerate`]: #method.enumerate - /// [`next`]: #tymethod.next + /// [`enumerate`]: Iterator::enumerate + /// [`next`]: Iterator::next #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> @@ -734,8 +728,8 @@ pub trait Iterator { /// Why `filter_map` and not just [`filter`] and [`map`]? The key is in this /// part: /// - /// [`filter`]: #method.filter - /// [`map`]: #method.map + /// [`filter`]: Iterator::filter + /// [`map`]: Iterator::map /// /// > If the closure returns [`Some(element)`][`Some`], then that element is returned. /// @@ -802,7 +796,7 @@ pub trait Iterator { /// /// [`usize`]: type@usize /// [`usize::MAX`]: crate::usize::MAX - /// [`zip`]: #method.zip + /// [`zip`]: Iterator::zip /// /// # Examples /// @@ -837,8 +831,8 @@ pub trait Iterator { /// anything other than fetching the next value) of the [`next`] method /// will occur. /// - /// [`peek`]: crate::iter::Peekable::peek - /// [`next`]: #tymethod.next + /// [`peek`]: Peekable::peek + /// [`next`]: Iterator::next /// /// # Examples /// @@ -876,7 +870,7 @@ pub trait Iterator { /// Creates an iterator that [`skip`]s elements based on a predicate. /// - /// [`skip`]: #method.skip + /// [`skip`]: Iterator::skip /// /// `skip_while()` takes a closure as an argument. It will call this /// closure on each element of the iterator, and ignore elements @@ -1043,8 +1037,8 @@ pub trait Iterator { /// /// Here's the same example, but with [`take_while`] and [`map`]: /// - /// [`take_while`]: #method.take_while - /// [`map`]: #method.map + /// [`take_while`]: Iterator::take_while + /// [`map`]: Iterator::map /// /// ``` /// let a = [-1i32, 4, 0, 1]; @@ -1104,7 +1098,7 @@ pub trait Iterator { /// It is also not specified what this iterator returns after the first` None` is returned. /// If you need fused iterator, use [`fuse`]. /// - /// [`fuse`]: #method.fuse + /// [`fuse`]: Iterator::fuse #[inline] #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> @@ -1190,7 +1184,7 @@ pub trait Iterator { /// An iterator adaptor similar to [`fold`] that holds internal state and /// produces a new iterator. /// - /// [`fold`]: #method.fold + /// [`fold`]: Iterator::fold /// /// `scan()` takes two arguments: an initial value which seeds the internal /// state, and a closure with two arguments, the first being a mutable @@ -1246,8 +1240,8 @@ pub trait Iterator { /// one item for each element, and `flat_map()`'s closure returns an /// iterator for each element. /// - /// [`map`]: #method.map - /// [`flatten`]: #method.flatten + /// [`map`]: Iterator::map + /// [`flatten`]: Iterator::flatten /// /// # Examples /// @@ -1333,7 +1327,7 @@ pub trait Iterator { /// two-dimensional and not one-dimensional. To get a one-dimensional /// structure, you have to `flatten()` again. /// - /// [`flat_map()`]: #method.flat_map + /// [`flat_map()`]: Iterator::flat_map #[inline] #[stable(feature = "iterator_flatten", since = "1.29.0")] fn flatten(self) -> Flatten<Self> @@ -1640,7 +1634,7 @@ pub trait Iterator { /// assert_eq!(Ok(vec![1, 3]), result); /// ``` /// - /// [`iter`]: #tymethod.next + /// [`iter`]: Iterator::next /// [`String`]: ../../std/string/struct.String.html /// [`char`]: type@char #[inline] @@ -1661,8 +1655,8 @@ pub trait Iterator { /// /// See also [`is_partitioned()`] and [`partition_in_place()`]. /// - /// [`is_partitioned()`]: #method.is_partitioned - /// [`partition_in_place()`]: #method.partition_in_place + /// [`is_partitioned()`]: Iterator::is_partitioned + /// [`partition_in_place()`]: Iterator::partition_in_place /// /// # Examples /// @@ -1716,8 +1710,8 @@ pub trait Iterator { /// /// See also [`is_partitioned()`] and [`partition()`]. /// - /// [`is_partitioned()`]: #method.is_partitioned - /// [`partition()`]: #method.partition + /// [`is_partitioned()`]: Iterator::is_partitioned + /// [`partition()`]: Iterator::partition /// /// # Examples /// @@ -1779,8 +1773,8 @@ pub trait Iterator { /// /// See also [`partition()`] and [`partition_in_place()`]. /// - /// [`partition()`]: #method.partition - /// [`partition_in_place()`]: #method.partition_in_place + /// [`partition()`]: Iterator::partition + /// [`partition_in_place()`]: Iterator::partition_in_place /// /// # Examples /// @@ -1879,8 +1873,8 @@ pub trait Iterator { /// This can also be thought of as the fallible form of [`for_each()`] /// or as the stateless version of [`try_fold()`]. /// - /// [`for_each()`]: #method.for_each - /// [`try_fold()`]: #method.try_fold + /// [`for_each()`]: Iterator::for_each + /// [`try_fold()`]: Iterator::try_fold /// /// # Examples /// @@ -2006,11 +2000,13 @@ pub trait Iterator { accum } - /// The same as [`fold()`](#method.fold), but uses the first element in the + /// The same as [`fold()`], but uses the first element in the /// iterator as the initial value, folding every subsequent element into it. /// If the iterator is empty, return `None`; otherwise, return the result /// of the fold. /// + /// [`fold()`]: Iterator::fold + /// /// # Example /// /// Find the maximum value: @@ -2088,12 +2084,12 @@ pub trait Iterator { F: FnMut(Self::Item) -> bool, { #[inline] - fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> { + fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { move |(), x| { - if f(x) { LoopState::Continue(()) } else { LoopState::Break(()) } + if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) } } } - self.try_fold((), check(f)) == LoopState::Continue(()) + self.try_fold((), check(f)) == ControlFlow::Continue(()) } /// Tests if any element of the iterator matches a predicate. @@ -2141,13 +2137,13 @@ pub trait Iterator { F: FnMut(Self::Item) -> bool, { #[inline] - fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> { + fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { move |(), x| { - if f(x) { LoopState::Break(()) } else { LoopState::Continue(()) } + if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } } } - self.try_fold((), check(f)) == LoopState::Break(()) + self.try_fold((), check(f)) == ControlFlow::Break(()) } /// Searches for an element of an iterator that satisfies a predicate. @@ -2203,9 +2199,9 @@ pub trait Iterator { #[inline] fn check<T>( mut predicate: impl FnMut(&T) -> bool, - ) -> impl FnMut((), T) -> LoopState<(), T> { + ) -> impl FnMut((), T) -> ControlFlow<(), T> { move |(), x| { - if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) } + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } } } @@ -2235,10 +2231,12 @@ pub trait Iterator { F: FnMut(Self::Item) -> Option<B>, { #[inline] - fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> LoopState<(), B> { + fn check<T, B>( + mut f: impl FnMut(T) -> Option<B>, + ) -> impl FnMut((), T) -> ControlFlow<(), B> { move |(), x| match f(x) { - Some(x) => LoopState::Break(x), - None => LoopState::Continue(()), + Some(x) => ControlFlow::Break(x), + None => ControlFlow::Continue(()), } } @@ -2274,15 +2272,15 @@ pub trait Iterator { R: Try<Ok = bool>, { #[inline] - fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> LoopState<(), Result<T, R::Error>> + fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>> where F: FnMut(&T) -> R, R: Try<Ok = bool>, { move |(), x| match f(&x).into_result() { - Ok(false) => LoopState::Continue(()), - Ok(true) => LoopState::Break(Ok(x)), - Err(x) => LoopState::Break(Err(x)), + Ok(false) => ControlFlow::Continue(()), + Ok(true) => ControlFlow::Break(Ok(x)), + Err(x) => ControlFlow::Break(Err(x)), } } @@ -2352,10 +2350,14 @@ pub trait Iterator { #[inline] fn check<T>( mut predicate: impl FnMut(T) -> bool, - ) -> impl FnMut(usize, T) -> LoopState<usize, usize> { + ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> { // The addition might panic on overflow move |i, x| { - if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(Add::add(i, 1)) } + if predicate(x) { + ControlFlow::Break(i) + } else { + ControlFlow::Continue(Add::add(i, 1)) + } } } @@ -2411,10 +2413,10 @@ pub trait Iterator { #[inline] fn check<T>( mut predicate: impl FnMut(T) -> bool, - ) -> impl FnMut(usize, T) -> LoopState<usize, usize> { + ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> { move |i, x| { let i = i - 1; - if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(i) } + if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i) } } } @@ -2602,8 +2604,6 @@ pub trait Iterator { /// This is only possible if the iterator has an end, so `rev()` only /// works on [`DoubleEndedIterator`]s. /// - /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html - /// /// # Examples /// /// ``` @@ -2634,7 +2634,7 @@ pub trait Iterator { /// /// This function is, in some sense, the opposite of [`zip`]. /// - /// [`zip`]: #method.zip + /// [`zip`]: Iterator::zip /// /// # Examples /// @@ -3078,6 +3078,7 @@ pub trait Iterator { /// assert_eq!([1].iter().lt([1].iter()), false); /// assert_eq!([1].iter().lt([1, 2].iter()), true); /// assert_eq!([1, 2].iter().lt([1].iter()), false); + /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] fn lt<I>(self, other: I) -> bool @@ -3098,6 +3099,7 @@ pub trait Iterator { /// assert_eq!([1].iter().le([1].iter()), true); /// assert_eq!([1].iter().le([1, 2].iter()), true); /// assert_eq!([1, 2].iter().le([1].iter()), false); + /// assert_eq!([1, 2].iter().le([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] fn le<I>(self, other: I) -> bool @@ -3118,6 +3120,7 @@ pub trait Iterator { /// assert_eq!([1].iter().gt([1].iter()), false); /// assert_eq!([1].iter().gt([1, 2].iter()), false); /// assert_eq!([1, 2].iter().gt([1].iter()), true); + /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] fn gt<I>(self, other: I) -> bool @@ -3138,6 +3141,7 @@ pub trait Iterator { /// assert_eq!([1].iter().ge([1].iter()), true); /// assert_eq!([1].iter().ge([1, 2].iter()), false); /// assert_eq!([1, 2].iter().ge([1].iter()), true); + /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] fn ge<I>(self, other: I) -> bool @@ -3197,7 +3201,7 @@ pub trait Iterator { /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b))); /// ``` /// - /// [`is_sorted`]: #method.is_sorted + /// [`is_sorted`]: Iterator::is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] fn is_sorted_by<F>(mut self, mut compare: F) -> bool where @@ -3226,7 +3230,7 @@ pub trait Iterator { /// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see /// its documentation for more information. /// - /// [`is_sorted`]: #method.is_sorted + /// [`is_sorted`]: Iterator::is_sorted /// /// # Examples /// diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 4e0da1fc4a6..a1b0821004b 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -242,7 +242,7 @@ macro_rules! debug_assert_ne { #[macro_export] #[stable(feature = "matches_macro", since = "1.42.0")] macro_rules! matches { - ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => { + ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => { match $expression { $( $pattern )|+ $( if $guard )? => true, _ => false diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index a02ee9c5ba9..9340b591ebd 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -111,13 +111,13 @@ pub trait Sized { /// - `T` is not part of the type of any other fields /// - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>` /// -/// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow -/// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized +/// `Unsize` is used along with [`ops::CoerceUnsized`] to allow +/// "user-defined" containers such as [`Rc`] to contain dynamically-sized /// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce] /// for more details. /// -/// [coerceunsized]: ../ops/trait.CoerceUnsized.html -/// [rc]: ../../std/rc/struct.Rc.html +/// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized +/// [`Rc`]: ../../std/rc/struct.Rc.html /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md /// [nomicon-coerce]: ../../nomicon/coercions.html #[unstable(feature = "unsize", issue = "27732")] @@ -368,11 +368,7 @@ pub trait StructuralEq { /// /// [`Vec<T>`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html -/// [`Drop`]: ../../std/ops/trait.Drop.html -/// [`size_of::<T>`]: ../../std/mem/fn.size_of.html -/// [`Clone`]: ../clone/trait.Clone.html -/// [`String`]: ../../std/string/struct.String.html -/// [`i32`]: ../../std/primitive.i32.html +/// [`size_of::<T>`]: crate::mem::size_of /// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "copy"] @@ -400,18 +396,18 @@ pub macro Copy($item:item) { /// This trait is automatically implemented when the compiler determines /// it's appropriate. /// -/// The precise definition is: a type `T` is `Sync` if and only if `&T` is -/// [`Send`][send]. In other words, if there is no possibility of +/// The precise definition is: a type `T` is [`Sync`] if and only if `&T` is +/// [`Send`]. In other words, if there is no possibility of /// [undefined behavior][ub] (including data races) when passing /// `&T` references between threads. /// -/// As one would expect, primitive types like [`u8`][u8] and [`f64`][f64] -/// are all `Sync`, and so are simple aggregate types containing them, -/// like tuples, structs and enums. More examples of basic `Sync` +/// As one would expect, primitive types like [`u8`] and [`f64`] +/// are all [`Sync`], and so are simple aggregate types containing them, +/// like tuples, structs and enums. More examples of basic [`Sync`] /// types include "immutable" types like `&T`, and those with simple /// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and -/// most other collection types. (Generic parameters need to be `Sync` -/// for their container to be `Sync`.) +/// most other collection types. (Generic parameters need to be [`Sync`] +/// for their container to be [`Sync`].) /// /// A somewhat surprising consequence of the definition is that `&mut T` /// is `Sync` (if `T` is `Sync`) even though it seems like that might @@ -421,15 +417,15 @@ pub macro Copy($item:item) { /// of a data race. /// /// Types that are not `Sync` are those that have "interior -/// mutability" in a non-thread-safe form, such as [`cell::Cell`][cell] -/// and [`cell::RefCell`][refcell]. These types allow for mutation of +/// mutability" in a non-thread-safe form, such as [`Cell`][cell] +/// and [`RefCell`][refcell]. These types allow for mutation of /// their contents even through an immutable, shared reference. For /// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires /// only a shared reference [`&Cell<T>`][cell]. The method performs no /// synchronization, thus [`Cell`][cell] cannot be `Sync`. /// /// Another example of a non-`Sync` type is the reference-counting -/// pointer [`rc::Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone +/// pointer [`Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone /// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way. /// /// For cases when one does need thread-safe interior mutability, @@ -445,24 +441,21 @@ pub macro Copy($item:item) { /// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing /// from `&T` to `&mut T` is invalid. /// -/// See [the Nomicon](../../nomicon/send-and-sync.html) for more -/// details about `Sync`. +/// See [the Nomicon][nomicon-send-and-sync] for more details about `Sync`. /// -/// [send]: trait.Send.html -/// [u8]: ../../std/primitive.u8.html -/// [f64]: ../../std/primitive.f64.html /// [box]: ../../std/boxed/struct.Box.html /// [vec]: ../../std/vec/struct.Vec.html -/// [cell]: ../cell/struct.Cell.html -/// [refcell]: ../cell/struct.RefCell.html +/// [cell]: crate::cell::Cell +/// [refcell]: crate::cell::RefCell /// [rc]: ../../std/rc/struct.Rc.html /// [arc]: ../../std/sync/struct.Arc.html -/// [atomic data types]: ../sync/atomic/index.html +/// [atomic data types]: crate::sync::atomic /// [mutex]: ../../std/sync/struct.Mutex.html /// [rwlock]: ../../std/sync/struct.RwLock.html -/// [unsafecell]: ../cell/struct.UnsafeCell.html +/// [unsafecell]: crate::cell::UnsafeCell /// [ub]: ../../reference/behavior-considered-undefined.html -/// [transmute]: ../../std/mem/fn.transmute.html +/// [transmute]: crate::mem::transmute +/// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "sync_trait")] #[lang = "sync"] @@ -698,7 +691,7 @@ mod impls { /// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute /// between `DiscriminantKind::Discriminant` and `mem::Discriminant`. /// -/// [`mem::Discriminant`]: https://doc.rust-lang.org/stable/core/mem/struct.Discriminant.html +/// [`mem::Discriminant`]: crate::mem::Discriminant #[unstable( feature = "discriminant_kind", issue = "none", @@ -733,7 +726,7 @@ unsafe impl<T: ?Sized> Freeze for &mut T {} /// /// The [`Pin`][Pin] type is used instead to prevent moves through the type /// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be -/// moved out of. See the [`pin module`] documentation for more information on +/// moved out of. See the [`pin` module] documentation for more information on /// pinning. /// /// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off @@ -764,9 +757,9 @@ unsafe impl<T: ?Sized> Freeze for &mut T {} /// /// This trait is automatically implemented for almost every type. /// -/// [`mem::replace`]: ../../std/mem/fn.replace.html +/// [`mem::replace`]: crate::mem::replace /// [Pin]: crate::pin::Pin -/// [`pin module`]: crate::pin +/// [`pin` module]: crate::pin #[stable(feature = "pin", since = "1.33.0")] #[rustc_on_unimplemented( on(_Self = "std::future::Future", note = "consider using `Box::pin`",), diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index d2d65fd2fa5..a79d9e25f34 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -369,7 +369,7 @@ impl<T> MaybeUninit<T> { pub fn write(&mut self, val: T) -> &mut T { unsafe { self.value = ManuallyDrop::new(val); - self.get_mut() + self.assume_init_mut() } } @@ -601,7 +601,7 @@ impl<T> MaybeUninit<T> { /// // create a shared reference to it: /// let x: &Vec<u32> = unsafe { /// // Safety: `x` has been initialized. - /// x.get_ref() + /// x.assume_init_ref() /// }; /// assert_eq!(x, &vec![1, 2, 3]); /// ``` @@ -613,7 +613,7 @@ impl<T> MaybeUninit<T> { /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::<Vec<u32>>::uninit(); - /// let x_vec: &Vec<u32> = unsafe { x.get_ref() }; + /// let x_vec: &Vec<u32> = unsafe { x.assume_init_ref() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️ /// ``` /// @@ -624,14 +624,14 @@ impl<T> MaybeUninit<T> { /// let b = MaybeUninit::<Cell<bool>>::uninit(); /// // Initialize the `MaybeUninit` using `Cell::set`: /// unsafe { - /// b.get_ref().set(true); - /// // ^^^^^^^^^^^ - /// // Reference to an uninitialized `Cell<bool>`: UB! + /// b.assume_init_ref().set(true); + /// // ^^^^^^^^^^^^^^^ + /// // Reference to an uninitialized `Cell<bool>`: UB! /// } /// ``` #[unstable(feature = "maybe_uninit_ref", issue = "63568")] #[inline(always)] - pub unsafe fn get_ref(&self) -> &T { + pub unsafe fn assume_init_ref(&self) -> &T { // SAFETY: the caller must guarantee that `self` is initialized. // This also means that `self` must be a `value` variant. unsafe { @@ -650,7 +650,7 @@ impl<T> MaybeUninit<T> { /// /// Calling this when the content is not yet fully initialized causes undefined /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really - /// is in an initialized state. For instance, `.get_mut()` cannot be used to + /// is in an initialized state. For instance, `.assume_init_mut()` cannot be used to /// initialize a `MaybeUninit`. /// /// # Examples @@ -678,7 +678,7 @@ impl<T> MaybeUninit<T> { /// // the `&mut MaybeUninit<[u8; 2048]>` to a `&mut [u8; 2048]`: /// let buf: &mut [u8; 2048] = unsafe { /// // Safety: `buf` has been initialized. - /// buf.get_mut() + /// buf.assume_init_mut() /// }; /// /// // Now we can use `buf` as a normal slice: @@ -691,7 +691,7 @@ impl<T> MaybeUninit<T> { /// /// ### *Incorrect* usages of this method: /// - /// You cannot use `.get_mut()` to initialize a value: + /// You cannot use `.assume_init_mut()` to initialize a value: /// /// ```rust,no_run /// #![feature(maybe_uninit_ref)] @@ -699,7 +699,7 @@ impl<T> MaybeUninit<T> { /// /// let mut b = MaybeUninit::<bool>::uninit(); /// unsafe { - /// *b.get_mut() = true; + /// *b.assume_init_mut() = true; /// // We have created a (mutable) reference to an uninitialized `bool`! /// // This is undefined behavior. ⚠️ /// } @@ -716,8 +716,8 @@ impl<T> MaybeUninit<T> { /// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]> /// { /// let mut buffer = MaybeUninit::<[u8; 64]>::uninit(); - /// reader.read_exact(unsafe { buffer.get_mut() })?; - /// // ^^^^^^^^^^^^^^^^ + /// reader.read_exact(unsafe { buffer.assume_init_mut() })?; + /// // ^^^^^^^^^^^^^^^^^^^^^^^^ /// // (mutable) reference to uninitialized memory! /// // This is undefined behavior. /// Ok(unsafe { buffer.assume_init() }) @@ -737,23 +737,23 @@ impl<T> MaybeUninit<T> { /// /// let foo: Foo = unsafe { /// let mut foo = MaybeUninit::<Foo>::uninit(); - /// ptr::write(&mut foo.get_mut().a as *mut u32, 1337); - /// // ^^^^^^^^^^^^^ + /// ptr::write(&mut foo.assume_init_mut().a as *mut u32, 1337); + /// // ^^^^^^^^^^^^^^^^^^^^^ /// // (mutable) reference to uninitialized memory! /// // This is undefined behavior. - /// ptr::write(&mut foo.get_mut().b as *mut u8, 42); - /// // ^^^^^^^^^^^^^ + /// ptr::write(&mut foo.assume_init_mut().b as *mut u8, 42); + /// // ^^^^^^^^^^^^^^^^^^^^^ /// // (mutable) reference to uninitialized memory! /// // This is undefined behavior. /// foo.assume_init() /// }; /// ``` - // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references + // FIXME(#76092): We currently rely on the above being incorrect, i.e., we have references // to uninitialized data (e.g., in `libcore/fmt/float.rs`). We should make // a final decision about the rules before stabilization. #[unstable(feature = "maybe_uninit_ref", issue = "63568")] #[inline(always)] - pub unsafe fn get_mut(&mut self) -> &mut T { + pub unsafe fn assume_init_mut(&mut self) -> &mut T { // SAFETY: the caller must guarantee that `self` is initialized. // This also means that `self` must be a `value` variant. unsafe { diff --git a/library/core/src/num/flt2dec/mod.rs b/library/core/src/num/flt2dec/mod.rs index 9bf56e93d89..1f28edb4128 100644 --- a/library/core/src/num/flt2dec/mod.rs +++ b/library/core/src/num/flt2dec/mod.rs @@ -124,6 +124,8 @@ functions. pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded}; +use crate::mem::MaybeUninit; + pub mod decoder; pub mod estimator; @@ -140,23 +142,23 @@ pub mod strategy { /// The exact formula is `ceil(# bits in mantissa * log_10 2 + 1)`. pub const MAX_SIG_DIGITS: usize = 17; -/// When `d[..n]` contains decimal digits, increase the last digit and propagate carry. -/// Returns a next digit when it causes the length change. +/// When `d` contains decimal digits, increase the last digit and propagate carry. +/// Returns a next digit when it causes the length to change. #[doc(hidden)] -pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> { - match d[..n].iter().rposition(|&c| c != b'9') { +pub fn round_up(d: &mut [u8]) -> Option<u8> { + match d.iter().rposition(|&c| c != b'9') { Some(i) => { // d[i+1..n] is all nines d[i] += 1; - for j in i + 1..n { + for j in i + 1..d.len() { d[j] = b'0'; } None } - None if n > 0 => { + None if d.len() > 0 => { // 999..999 rounds to 1000..000 with an increased exponent d[0] = b'1'; - for j in 1..n { + for j in 1..d.len() { d[j] = b'0'; } Some(b'0') @@ -281,7 +283,7 @@ fn digits_to_dec_str<'a>( buf: &'a [u8], exp: i16, frac_digits: usize, - parts: &'a mut [Part<'a>], + parts: &'a mut [MaybeUninit<Part<'a>>], ) -> &'a [Part<'a>] { assert!(!buf.is_empty()); assert!(buf[0] > b'0'); @@ -303,38 +305,44 @@ fn digits_to_dec_str<'a>( if exp <= 0 { // the decimal point is before rendered digits: [0.][000...000][1234][____] let minus_exp = -(exp as i32) as usize; - parts[0] = Part::Copy(b"0."); - parts[1] = Part::Zero(minus_exp); - parts[2] = Part::Copy(buf); + parts[0] = MaybeUninit::new(Part::Copy(b"0.")); + parts[1] = MaybeUninit::new(Part::Zero(minus_exp)); + parts[2] = MaybeUninit::new(Part::Copy(buf)); if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp { - parts[3] = Part::Zero((frac_digits - buf.len()) - minus_exp); - &parts[..4] + parts[3] = MaybeUninit::new(Part::Zero((frac_digits - buf.len()) - minus_exp)); + // SAFETY: we just initialized the elements `..4`. + unsafe { MaybeUninit::slice_get_ref(&parts[..4]) } } else { - &parts[..3] + // SAFETY: we just initialized the elements `..3`. + unsafe { MaybeUninit::slice_get_ref(&parts[..3]) } } } else { let exp = exp as usize; if exp < buf.len() { // the decimal point is inside rendered digits: [12][.][34][____] - parts[0] = Part::Copy(&buf[..exp]); - parts[1] = Part::Copy(b"."); - parts[2] = Part::Copy(&buf[exp..]); + parts[0] = MaybeUninit::new(Part::Copy(&buf[..exp])); + parts[1] = MaybeUninit::new(Part::Copy(b".")); + parts[2] = MaybeUninit::new(Part::Copy(&buf[exp..])); if frac_digits > buf.len() - exp { - parts[3] = Part::Zero(frac_digits - (buf.len() - exp)); - &parts[..4] + parts[3] = MaybeUninit::new(Part::Zero(frac_digits - (buf.len() - exp))); + // SAFETY: we just initialized the elements `..4`. + unsafe { MaybeUninit::slice_get_ref(&parts[..4]) } } else { - &parts[..3] + // SAFETY: we just initialized the elements `..3`. + unsafe { MaybeUninit::slice_get_ref(&parts[..3]) } } } else { // the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__]. - parts[0] = Part::Copy(buf); - parts[1] = Part::Zero(exp - buf.len()); + parts[0] = MaybeUninit::new(Part::Copy(buf)); + parts[1] = MaybeUninit::new(Part::Zero(exp - buf.len())); if frac_digits > 0 { - parts[2] = Part::Copy(b"."); - parts[3] = Part::Zero(frac_digits); - &parts[..4] + parts[2] = MaybeUninit::new(Part::Copy(b".")); + parts[3] = MaybeUninit::new(Part::Zero(frac_digits)); + // SAFETY: we just initialized the elements `..4`. + unsafe { MaybeUninit::slice_get_ref(&parts[..4]) } } else { - &parts[..2] + // SAFETY: we just initialized the elements `..2`. + unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } } } } @@ -354,7 +362,7 @@ fn digits_to_exp_str<'a>( exp: i16, min_ndigits: usize, upper: bool, - parts: &'a mut [Part<'a>], + parts: &'a mut [MaybeUninit<Part<'a>>], ) -> &'a [Part<'a>] { assert!(!buf.is_empty()); assert!(buf[0] > b'0'); @@ -362,15 +370,15 @@ fn digits_to_exp_str<'a>( let mut n = 0; - parts[n] = Part::Copy(&buf[..1]); + parts[n] = MaybeUninit::new(Part::Copy(&buf[..1])); n += 1; if buf.len() > 1 || min_ndigits > 1 { - parts[n] = Part::Copy(b"."); - parts[n + 1] = Part::Copy(&buf[1..]); + parts[n] = MaybeUninit::new(Part::Copy(b".")); + parts[n + 1] = MaybeUninit::new(Part::Copy(&buf[1..])); n += 2; if min_ndigits > buf.len() { - parts[n] = Part::Zero(min_ndigits - buf.len()); + parts[n] = MaybeUninit::new(Part::Zero(min_ndigits - buf.len())); n += 1; } } @@ -378,13 +386,14 @@ fn digits_to_exp_str<'a>( // 0.1234 x 10^exp = 1.234 x 10^(exp-1) let exp = exp as i32 - 1; // avoid underflow when exp is i16::MIN if exp < 0 { - parts[n] = Part::Copy(if upper { b"E-" } else { b"e-" }); - parts[n + 1] = Part::Num(-exp as u16); + parts[n] = MaybeUninit::new(Part::Copy(if upper { b"E-" } else { b"e-" })); + parts[n + 1] = MaybeUninit::new(Part::Num(-exp as u16)); } else { - parts[n] = Part::Copy(if upper { b"E" } else { b"e" }); - parts[n + 1] = Part::Num(exp as u16); + parts[n] = MaybeUninit::new(Part::Copy(if upper { b"E" } else { b"e" })); + parts[n + 1] = MaybeUninit::new(Part::Num(exp as u16)); } - &parts[..n + 2] + // SAFETY: we just initialized the elements `..n + 2`. + unsafe { MaybeUninit::slice_get_ref(&parts[..n + 2]) } } /// Sign formatting options. @@ -446,6 +455,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static /// (which can be an empty string if no sign is rendered). /// /// `format_shortest` should be the underlying digit-generation function. +/// It should return the part of the buffer that it initialized. /// You probably would want `strategy::grisu::format_shortest` for this. /// /// `frac_digits` can be less than the number of actual fractional digits in `v`; @@ -461,12 +471,12 @@ pub fn to_shortest_str<'a, T, F>( v: T, sign: Sign, frac_digits: usize, - buf: &'a mut [u8], - parts: &'a mut [Part<'a>], + buf: &'a mut [MaybeUninit<u8>], + parts: &'a mut [MaybeUninit<Part<'a>>], ) -> Formatted<'a> where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { assert!(parts.len() >= 4); assert!(buf.len() >= MAX_SIG_DIGITS); @@ -475,27 +485,31 @@ where let sign = determine_sign(sign, &full_decoded, negative); match full_decoded { FullDecoded::Nan => { - parts[0] = Part::Copy(b"NaN"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Infinite => { - parts[0] = Part::Copy(b"inf"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"inf")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Zero => { if frac_digits > 0 { // [0.][0000] - parts[0] = Part::Copy(b"0."); - parts[1] = Part::Zero(frac_digits); - Formatted { sign, parts: &parts[..2] } + parts[0] = MaybeUninit::new(Part::Copy(b"0.")); + parts[1] = MaybeUninit::new(Part::Zero(frac_digits)); + // SAFETY: we just initialized the elements `..2`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } } } else { - parts[0] = Part::Copy(b"0"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"0")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } } FullDecoded::Finite(ref decoded) => { - let (len, exp) = format_shortest(decoded, buf); - Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } + let (buf, exp) = format_shortest(decoded, buf); + Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) } } } } @@ -509,6 +523,7 @@ where /// an empty string if no sign is rendered). /// /// `format_shortest` should be the underlying digit-generation function. +/// It should return the part of the buffer that it initialized. /// You probably would want `strategy::grisu::format_shortest` for this. /// /// The `dec_bounds` is a tuple `(lo, hi)` such that the number is formatted @@ -525,12 +540,12 @@ pub fn to_shortest_exp_str<'a, T, F>( sign: Sign, dec_bounds: (i16, i16), upper: bool, - buf: &'a mut [u8], - parts: &'a mut [Part<'a>], + buf: &'a mut [MaybeUninit<u8>], + parts: &'a mut [MaybeUninit<Part<'a>>], ) -> Formatted<'a> where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { assert!(parts.len() >= 6); assert!(buf.len() >= MAX_SIG_DIGITS); @@ -540,28 +555,31 @@ where let sign = determine_sign(sign, &full_decoded, negative); match full_decoded { FullDecoded::Nan => { - parts[0] = Part::Copy(b"NaN"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Infinite => { - parts[0] = Part::Copy(b"inf"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"inf")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Zero => { parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 { - Part::Copy(b"0") + MaybeUninit::new(Part::Copy(b"0")) } else { - Part::Copy(if upper { b"0E0" } else { b"0e0" }) + MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" })) }; - Formatted { sign, parts: &parts[..1] } + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Finite(ref decoded) => { - let (len, exp) = format_shortest(decoded, buf); + let (buf, exp) = format_shortest(decoded, buf); let vis_exp = exp as i32 - 1; let parts = if dec_bounds.0 as i32 <= vis_exp && vis_exp < dec_bounds.1 as i32 { - digits_to_dec_str(&buf[..len], exp, 0, parts) + digits_to_dec_str(buf, exp, 0, parts) } else { - digits_to_exp_str(&buf[..len], exp, 0, upper, parts) + digits_to_exp_str(buf, exp, 0, upper, parts) }; Formatted { sign, parts } } @@ -600,6 +618,7 @@ fn estimate_max_buf_len(exp: i16) -> usize { /// an empty string if no sign is rendered). /// /// `format_exact` should be the underlying digit-generation function. +/// It should return the part of the buffer that it initialized. /// You probably would want `strategy::grisu::format_exact` for this. /// /// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is @@ -613,12 +632,12 @@ pub fn to_exact_exp_str<'a, T, F>( sign: Sign, ndigits: usize, upper: bool, - buf: &'a mut [u8], - parts: &'a mut [Part<'a>], + buf: &'a mut [MaybeUninit<u8>], + parts: &'a mut [MaybeUninit<Part<'a>>], ) -> Formatted<'a> where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { assert!(parts.len() >= 6); assert!(ndigits > 0); @@ -627,23 +646,27 @@ where let sign = determine_sign(sign, &full_decoded, negative); match full_decoded { FullDecoded::Nan => { - parts[0] = Part::Copy(b"NaN"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Infinite => { - parts[0] = Part::Copy(b"inf"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"inf")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Zero => { if ndigits > 1 { // [0.][0000][e0] - parts[0] = Part::Copy(b"0."); - parts[1] = Part::Zero(ndigits - 1); - parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" }); - Formatted { sign, parts: &parts[..3] } + parts[0] = MaybeUninit::new(Part::Copy(b"0.")); + parts[1] = MaybeUninit::new(Part::Zero(ndigits - 1)); + parts[2] = MaybeUninit::new(Part::Copy(if upper { b"E0" } else { b"e0" })); + // SAFETY: we just initialized the elements `..3`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..3]) } } } else { - parts[0] = Part::Copy(if upper { b"0E0" } else { b"0e0" }); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" })); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } } FullDecoded::Finite(ref decoded) => { @@ -651,8 +674,8 @@ where assert!(buf.len() >= ndigits || buf.len() >= maxlen); let trunc = if ndigits < maxlen { ndigits } else { maxlen }; - let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN); - Formatted { sign, parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) } + let (buf, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN); + Formatted { sign, parts: digits_to_exp_str(buf, exp, ndigits, upper, parts) } } } } @@ -665,6 +688,7 @@ where /// (which can be an empty string if no sign is rendered). /// /// `format_exact` should be the underlying digit-generation function. +/// It should return the part of the buffer that it initialized. /// You probably would want `strategy::grisu::format_exact` for this. /// /// The byte buffer should be enough for the output unless `frac_digits` is @@ -677,12 +701,12 @@ pub fn to_exact_fixed_str<'a, T, F>( v: T, sign: Sign, frac_digits: usize, - buf: &'a mut [u8], - parts: &'a mut [Part<'a>], + buf: &'a mut [MaybeUninit<u8>], + parts: &'a mut [MaybeUninit<Part<'a>>], ) -> Formatted<'a> where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { assert!(parts.len() >= 4); @@ -690,22 +714,26 @@ where let sign = determine_sign(sign, &full_decoded, negative); match full_decoded { FullDecoded::Nan => { - parts[0] = Part::Copy(b"NaN"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"NaN")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Infinite => { - parts[0] = Part::Copy(b"inf"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"inf")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } FullDecoded::Zero => { if frac_digits > 0 { // [0.][0000] - parts[0] = Part::Copy(b"0."); - parts[1] = Part::Zero(frac_digits); - Formatted { sign, parts: &parts[..2] } + parts[0] = MaybeUninit::new(Part::Copy(b"0.")); + parts[1] = MaybeUninit::new(Part::Zero(frac_digits)); + // SAFETY: we just initialized the elements `..2`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } } } else { - parts[0] = Part::Copy(b"0"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"0")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } } FullDecoded::Finite(ref decoded) => { @@ -716,23 +744,25 @@ where // `format_exact` will end rendering digits much earlier in this case, // because we are strictly limited by `maxlen`. let limit = if frac_digits < 0x8000 { -(frac_digits as i16) } else { i16::MIN }; - let (len, exp) = format_exact(decoded, &mut buf[..maxlen], limit); + let (buf, exp) = format_exact(decoded, &mut buf[..maxlen], limit); if exp <= limit { // the restriction couldn't been met, so this should render like zero no matter // `exp` was. this does not include the case that the restriction has been met // only after the final rounding-up; it's a regular case with `exp = limit + 1`. - debug_assert_eq!(len, 0); + debug_assert_eq!(buf.len(), 0); if frac_digits > 0 { // [0.][0000] - parts[0] = Part::Copy(b"0."); - parts[1] = Part::Zero(frac_digits); - Formatted { sign, parts: &parts[..2] } + parts[0] = MaybeUninit::new(Part::Copy(b"0.")); + parts[1] = MaybeUninit::new(Part::Zero(frac_digits)); + // SAFETY: we just initialized the elements `..2`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..2]) } } } else { - parts[0] = Part::Copy(b"0"); - Formatted { sign, parts: &parts[..1] } + parts[0] = MaybeUninit::new(Part::Copy(b"0")); + // SAFETY: we just initialized the elements `..1`. + Formatted { sign, parts: unsafe { MaybeUninit::slice_get_ref(&parts[..1]) } } } } else { - Formatted { sign, parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } + Formatted { sign, parts: digits_to_dec_str(buf, exp, frac_digits, parts) } } } } diff --git a/library/core/src/num/flt2dec/strategy/dragon.rs b/library/core/src/num/flt2dec/strategy/dragon.rs index c8de0004352..8cb6763cdbe 100644 --- a/library/core/src/num/flt2dec/strategy/dragon.rs +++ b/library/core/src/num/flt2dec/strategy/dragon.rs @@ -5,6 +5,7 @@ //! quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116. use crate::cmp::Ordering; +use crate::mem::MaybeUninit; use crate::num::bignum::Big32x40 as Big; use crate::num::bignum::Digit32 as Digit; @@ -97,7 +98,10 @@ fn div_rem_upto_16<'a>( } /// The shortest mode implementation for Dragon. -pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) { +pub fn format_shortest<'a>( + d: &Decoded, + buf: &'a mut [MaybeUninit<u8>], +) -> (/*digits*/ &'a [u8], /*exp*/ i16) { // the number `v` to format is known to be: // - equal to `mant * 2^exp`; // - preceded by `(mant - 2 * minus) * 2^exp` in the original type; and @@ -186,7 +190,7 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp // generate one digit: `d[n] = floor(mant / scale) < 10`. let (d, _) = div_rem_upto_16(&mut mant, &scale, &scale2, &scale4, &scale8); debug_assert!(d < 10); - buf[i] = b'0' + d; + buf[i] = MaybeUninit::new(b'0' + d); i += 1; // this is a simplified description of the modified Dragon algorithm. @@ -241,18 +245,24 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp // if rounding up changes the length, the exponent should also change. // it seems that this condition is very hard to satisfy (possibly impossible), // but we are just being safe and consistent here. - if let Some(c) = round_up(buf, i) { - buf[i] = c; + // SAFETY: we initialized that memory above. + if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) }) { + buf[i] = MaybeUninit::new(c); i += 1; k += 1; } } - (i, k) + // SAFETY: we initialized that memory above. + (unsafe { MaybeUninit::slice_get_ref(&buf[..i]) }, k) } /// The exact and fixed mode implementation for Dragon. -pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) { +pub fn format_exact<'a>( + d: &Decoded, + buf: &'a mut [MaybeUninit<u8>], + limit: i16, +) -> (/*digits*/ &'a [u8], /*exp*/ i16) { assert!(d.mant > 0); assert!(d.minus > 0); assert!(d.plus > 0); @@ -319,9 +329,10 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi // following digits are all zeroes, we stop here // do *not* try to perform rounding! rather, fill remaining digits. for c in &mut buf[i..len] { - *c = b'0'; + *c = MaybeUninit::new(b'0'); } - return (len, k); + // SAFETY: we initialized that memory above. + return (unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, k); } let mut d = 0; @@ -343,7 +354,7 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi } debug_assert!(mant < scale); debug_assert!(d < 10); - buf[i] = b'0' + d; + buf[i] = MaybeUninit::new(b'0' + d); mant.mul_small(10); } } @@ -353,21 +364,25 @@ pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usi // round to even (i.e., avoid rounding up when the prior digit is even). let order = mant.cmp(scale.mul_small(5)); if order == Ordering::Greater - || (order == Ordering::Equal && (len == 0 || buf[len - 1] & 1 == 1)) + || (order == Ordering::Equal + // SAFETY: `buf[len-1]` is initialized. + && (len == 0 || unsafe { buf[len - 1].assume_init() } & 1 == 1)) { // if rounding up changes the length, the exponent should also change. // but we've been requested a fixed number of digits, so do not alter the buffer... - if let Some(c) = round_up(buf, len) { + // SAFETY: we initialized that memory above. + if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..len]) }) { // ...unless we've been requested the fixed precision instead. // we also need to check that, if the original buffer was empty, // the additional digit can only be added when `k == limit` (edge case). k += 1; if k > limit && len < buf.len() { - buf[len] = c; + buf[len] = MaybeUninit::new(c); len += 1; } } } - (len, k) + // SAFETY: we initialized that memory above. + (unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, k) } diff --git a/library/core/src/num/flt2dec/strategy/grisu.rs b/library/core/src/num/flt2dec/strategy/grisu.rs index 1e2db212dd0..ed1dd654a3a 100644 --- a/library/core/src/num/flt2dec/strategy/grisu.rs +++ b/library/core/src/num/flt2dec/strategy/grisu.rs @@ -5,6 +5,7 @@ //! [^1]: Florian Loitsch. 2010. Printing floating-point numbers quickly and //! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243. +use crate::mem::MaybeUninit; use crate::num::diy_float::Fp; use crate::num::flt2dec::{round_up, Decoded, MAX_SIG_DIGITS}; @@ -161,10 +162,10 @@ pub fn max_pow10_no_more_than(x: u32) -> (u8, u32) { /// The shortest mode implementation for Grisu. /// /// It returns `None` when it would return an inexact representation otherwise. -pub fn format_shortest_opt( +pub fn format_shortest_opt<'a>( d: &Decoded, - buf: &mut [u8], -) -> Option<(/*#digits*/ usize, /*exp*/ i16)> { + buf: &'a mut [MaybeUninit<u8>], +) -> Option<(/*digits*/ &'a [u8], /*exp*/ i16)> { assert!(d.mant > 0); assert!(d.minus > 0); assert!(d.plus > 0); @@ -266,14 +267,23 @@ pub fn format_shortest_opt( let q = remainder / ten_kappa; let r = remainder % ten_kappa; debug_assert!(q < 10); - buf[i] = b'0' + q as u8; + buf[i] = MaybeUninit::new(b'0' + q as u8); i += 1; let plus1rem = ((r as u64) << e) + plus1frac; // == (plus1 % 10^kappa) * 2^e if plus1rem < delta1 { // `plus1 % 10^kappa < delta1 = plus1 - minus1`; we've found the correct `kappa`. let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent - return round_and_weed(&mut buf[..i], exp, plus1rem, delta1, plus1 - v.f, ten_kappa, 1); + return round_and_weed( + // SAFETY: we initialized that memory above. + unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) }, + exp, + plus1rem, + delta1, + plus1 - v.f, + ten_kappa, + 1, + ); } // break the loop when we have rendered all integral digits. @@ -310,13 +320,14 @@ pub fn format_shortest_opt( let q = remainder >> e; let r = remainder & ((1 << e) - 1); debug_assert!(q < 10); - buf[i] = b'0' + q as u8; + buf[i] = MaybeUninit::new(b'0' + q as u8); i += 1; if r < threshold { let ten_kappa = 1 << e; // implicit divisor return round_and_weed( - &mut buf[..i], + // SAFETY: we initialized that memory above. + unsafe { MaybeUninit::slice_get_mut(&mut buf[..i]) }, exp, r, threshold, @@ -355,7 +366,7 @@ pub fn format_shortest_opt( plus1v: u64, ten_kappa: u64, ulp: u64, - ) -> Option<(usize, i16)> { + ) -> Option<(&[u8], i16)> { assert!(!buf.is_empty()); // produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps. @@ -437,20 +448,22 @@ pub fn format_shortest_opt( // this is too liberal, though, so we reject any `w(n)` not between `plus0` and `minus0`, // i.e., `plus1 - plus1w(n) <= minus0` or `plus1 - plus1w(n) >= plus0`. we utilize the facts // that `threshold = plus1 - minus1` and `plus1 - plus0 = minus0 - minus1 = 2 ulp`. - if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp { - Some((buf.len(), exp)) - } else { - None - } + if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp { Some((buf, exp)) } else { None } } } /// The shortest mode implementation for Grisu with Dragon fallback. /// /// This should be used for most cases. -pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) { +pub fn format_shortest<'a>( + d: &Decoded, + buf: &'a mut [MaybeUninit<u8>], +) -> (/*digits*/ &'a [u8], /*exp*/ i16) { use crate::num::flt2dec::strategy::dragon::format_shortest as fallback; - match format_shortest_opt(d, buf) { + // SAFETY: The borrow checker is not smart enough to let us use `buf` + // in the second branch, so we launder the lifetime here. But we only re-use + // `buf` if `format_shortest_opt` returned `None` so this is okay. + match format_shortest_opt(d, unsafe { &mut *(buf as *mut _) }) { Some(ret) => ret, None => fallback(d, buf), } @@ -459,11 +472,11 @@ pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp /// The exact and fixed mode implementation for Grisu. /// /// It returns `None` when it would return an inexact representation otherwise. -pub fn format_exact_opt( +pub fn format_exact_opt<'a>( d: &Decoded, - buf: &mut [u8], + buf: &'a mut [MaybeUninit<u8>], limit: i16, -) -> Option<(/*#digits*/ usize, /*exp*/ i16)> { +) -> Option<(/*digits*/ &'a [u8], /*exp*/ i16)> { assert!(d.mant > 0); assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision assert!(!buf.is_empty()); @@ -510,7 +523,11 @@ pub fn format_exact_opt( // thus we are being sloppy here and widen the error range by a factor of 10. // this will increase the false negative rate, but only very, *very* slightly; // it can only matter noticeably when the mantissa is bigger than 60 bits. - return possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e); + // + // SAFETY: `len=0`, so the obligation of having initialized this memory is trivial. + return unsafe { + possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e) + }; } else if ((exp as i32 - limit as i32) as usize) < buf.len() { (exp - limit) as usize } else { @@ -534,13 +551,16 @@ pub fn format_exact_opt( let q = remainder / ten_kappa; let r = remainder % ten_kappa; debug_assert!(q < 10); - buf[i] = b'0' + q as u8; + buf[i] = MaybeUninit::new(b'0' + q as u8); i += 1; // is the buffer full? run the rounding pass with the remainder. if i == len { let vrem = ((r as u64) << e) + vfrac; // == (v % 10^kappa) * 2^e - return possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e); + // SAFETY: we have initialized `len` many bytes. + return unsafe { + possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e) + }; } // break the loop when we have rendered all integral digits. @@ -585,12 +605,13 @@ pub fn format_exact_opt( let q = remainder >> e; let r = remainder & ((1 << e) - 1); debug_assert!(q < 10); - buf[i] = b'0' + q as u8; + buf[i] = MaybeUninit::new(b'0' + q as u8); i += 1; // is the buffer full? run the rounding pass with the remainder. if i == len { - return possibly_round(buf, len, exp, limit, r, 1 << e, err); + // SAFETY: we have initialized `len` many bytes. + return unsafe { possibly_round(buf, len, exp, limit, r, 1 << e, err) }; } // restore invariants @@ -610,15 +631,17 @@ pub fn format_exact_opt( // - `remainder = (v % 10^kappa) * k` // - `ten_kappa = 10^kappa * k` // - `ulp = 2^-e * k` - fn possibly_round( - buf: &mut [u8], + // + // SAFETY: the first `len` bytes of `buf` must be initialized. + unsafe fn possibly_round( + buf: &mut [MaybeUninit<u8>], mut len: usize, mut exp: i16, limit: i16, remainder: u64, ten_kappa: u64, ulp: u64, - ) -> Option<(usize, i16)> { + ) -> Option<(&[u8], i16)> { debug_assert!(remainder < ten_kappa); // 10^kappa @@ -677,7 +700,8 @@ pub fn format_exact_opt( // we've already verified that `ulp < 10^kappa / 2`, so as long as // `10^kappa` did not overflow after all, the second check is fine. if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp { - return Some((len, exp)); + // SAFETY: our caller initialized that memory. + return Some((unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, exp)); } // :<------- remainder ------>| : @@ -698,17 +722,19 @@ pub fn format_exact_opt( // as `10^kappa` is never zero). also note that `remainder - ulp <= 10^kappa`, // so the second check does not overflow. if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp { - if let Some(c) = round_up(buf, len) { + // SAFETY: our caller must have initialized that memory. + if let Some(c) = round_up(unsafe { MaybeUninit::slice_get_mut(&mut buf[..len]) }) { // only add an additional digit when we've been requested the fixed precision. // we also need to check that, if the original buffer was empty, // the additional digit can only be added when `exp == limit` (edge case). exp += 1; if exp > limit && len < buf.len() { - buf[len] = c; + buf[len] = MaybeUninit::new(c); len += 1; } } - return Some((len, exp)); + // SAFETY: we and our caller initialized that memory. + return Some((unsafe { MaybeUninit::slice_get_ref(&buf[..len]) }, exp)); } // otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are @@ -720,9 +746,16 @@ pub fn format_exact_opt( /// The exact and fixed mode implementation for Grisu with Dragon fallback. /// /// This should be used for most cases. -pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) { +pub fn format_exact<'a>( + d: &Decoded, + buf: &'a mut [MaybeUninit<u8>], + limit: i16, +) -> (/*digits*/ &'a [u8], /*exp*/ i16) { use crate::num::flt2dec::strategy::dragon::format_exact as fallback; - match format_exact_opt(d, buf, limit) { + // SAFETY: The borrow checker is not smart enough to let us use `buf` + // in the second branch, so we launder the lifetime here. But we only re-use + // `buf` if `format_exact_opt` returned `None` so this is okay. + match format_exact_opt(d, unsafe { &mut *(buf as *mut _) }, limit) { Some(ret) => ret, None => fallback(d, buf, limit), } diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs new file mode 100644 index 00000000000..687d423dcb6 --- /dev/null +++ b/library/core/src/ops/control_flow.rs @@ -0,0 +1,67 @@ +use crate::ops::Try; + +/// Used to make try_fold closures more like normal loops +#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ControlFlow<C, B> { + /// Continue in the loop, using the given value for the next iteration + Continue(C), + /// Exit the loop, yielding the given value + Break(B), +} + +#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] +impl<C, B> Try for ControlFlow<C, B> { + type Ok = C; + type Error = B; + #[inline] + fn into_result(self) -> Result<Self::Ok, Self::Error> { + match self { + ControlFlow::Continue(y) => Ok(y), + ControlFlow::Break(x) => Err(x), + } + } + #[inline] + fn from_error(v: Self::Error) -> Self { + ControlFlow::Break(v) + } + #[inline] + fn from_ok(v: Self::Ok) -> Self { + ControlFlow::Continue(v) + } +} + +impl<C, B> ControlFlow<C, B> { + /// Converts the `ControlFlow` into an `Option` which is `Some` if the + /// `ControlFlow` was `Break` and `None` otherwise. + #[inline] + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + pub fn break_value(self) -> Option<B> { + match self { + ControlFlow::Continue(..) => None, + ControlFlow::Break(x) => Some(x), + } + } +} + +impl<R: Try> ControlFlow<R::Ok, R> { + /// Create a `ControlFlow` from any type implementing `Try`. + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + #[inline] + pub fn from_try(r: R) -> Self { + match Try::into_result(r) { + Ok(v) => ControlFlow::Continue(v), + Err(v) => ControlFlow::Break(Try::from_error(v)), + } + } + + /// Convert a `ControlFlow` into any type implementing `Try`; + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + #[inline] + pub fn into_try(self) -> R { + match self { + ControlFlow::Continue(v) => Try::from_ok(v), + ControlFlow::Break(v) => v, + } + } +} diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index c19bd6e441e..2a4186f9d5d 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -140,6 +140,7 @@ mod arith; mod bit; +mod control_flow; mod deref; mod drop; mod function; @@ -191,3 +192,6 @@ pub use self::unsize::CoerceUnsized; #[unstable(feature = "dispatch_from_dyn", issue = "none")] pub use self::unsize::DispatchFromDyn; + +#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] +pub use self::control_flow::ControlFlow; diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 316ecafe572..25ee73c626e 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -92,8 +92,6 @@ impl<'a> PanicInfo<'a> { /// If the `panic!` macro from the `core` crate (not from `std`) /// was used with a formatting string and some additional arguments, /// returns that message ready to be used for example with [`fmt::write`] - /// - /// [`fmt::write`]: ../fmt/fn.write.html #[unstable(feature = "panic_info_message", issue = "66745")] pub fn message(&self) -> Option<&fmt::Arguments<'_>> { self.message @@ -105,8 +103,6 @@ impl<'a> PanicInfo<'a> { /// This method will currently always return [`Some`], but this may change /// in future versions. /// - /// [`Some`]: ../../std/option/enum.Option.html#variant.Some - /// /// # Examples /// /// ```should_panic @@ -153,10 +149,7 @@ impl fmt::Display for PanicInfo<'_> { /// A struct containing information about the location of a panic. /// -/// This structure is created by the [`location`] method of [`PanicInfo`]. -/// -/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location -/// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html +/// This structure is created by [`PanicInfo::location()`]. /// /// # Examples /// diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 8f60c4787d4..a12a22fa26d 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -661,7 +661,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { /// because it is one of the fields of that value), and also that you do /// not move out of the argument you receive to the interior function. /// - /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning + /// [`pin` module]: self#projections-and-structural-pinning #[stable(feature = "pin", since = "1.33.0")] pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U> where @@ -692,7 +692,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { /// the `Pin` itself. This method allows turning the `Pin` into a reference /// with the same lifetime as the original `Pin`. /// - /// ["pinning projections"]: ../../std/pin/index.html#projections-and-structural-pinning + /// ["pinning projections"]: self#projections-and-structural-pinning #[stable(feature = "pin", since = "1.33.0")] #[inline(always)] pub fn get_ref(self) -> &'a T { @@ -756,7 +756,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { /// because it is one of the fields of that value), and also that you do /// not move out of the argument you receive to the interior function. /// - /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning + /// [`pin` module]: self#projections-and-structural-pinning #[stable(feature = "pin", since = "1.33.0")] pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U> where diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 4dcb91d63c9..503f015e76a 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -288,10 +288,12 @@ impl<T> [T] { /// Returns a reference to an element or subslice, without doing bounds /// checking. /// - /// This is generally not recommended, use with caution! + /// For a safe alternative see [`get`]. + /// + /// # Safety + /// /// Calling this method with an out-of-bounds index is *[undefined behavior]* /// even if the resulting reference is not used. - /// For a safe alternative see [`get`]. /// /// [`get`]: #method.get /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html @@ -320,10 +322,12 @@ impl<T> [T] { /// Returns a mutable reference to an element or subslice, without doing /// bounds checking. /// - /// This is generally not recommended, use with caution! + /// For a safe alternative see [`get_mut`]. + /// + /// # Safety + /// /// Calling this method with an out-of-bounds index is *[undefined behavior]* /// even if the resulting reference is not used. - /// For a safe alternative see [`get_mut`]. /// /// [`get_mut`]: #method.get_mut /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html @@ -865,8 +869,9 @@ impl<T> [T] { pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> { assert_ne!(chunk_size, 0); let rem = self.len() % chunk_size; - let len = self.len() - rem; - let (fst, snd) = self.split_at(len); + let fst_len = self.len() - rem; + // SAFETY: 0 <= fst_len <= self.len() by construction above + let (fst, snd) = unsafe { self.split_at_unchecked(fst_len) }; ChunksExact { v: fst, rem: snd, chunk_size } } @@ -910,8 +915,9 @@ impl<T> [T] { pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> { assert_ne!(chunk_size, 0); let rem = self.len() % chunk_size; - let len = self.len() - rem; - let (fst, snd) = self.split_at_mut(len); + let fst_len = self.len() - rem; + // SAFETY: 0 <= fst_len <= self.len() by construction above + let (fst, snd) = unsafe { self.split_at_mut_unchecked(fst_len) }; ChunksExactMut { v: fst, rem: snd, chunk_size } } @@ -1063,7 +1069,8 @@ impl<T> [T] { pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> { assert!(chunk_size != 0); let rem = self.len() % chunk_size; - let (fst, snd) = self.split_at(rem); + // SAFETY: 0 <= rem <= self.len() by construction above + let (fst, snd) = unsafe { self.split_at_unchecked(rem) }; RChunksExact { v: snd, rem: fst, chunk_size } } @@ -1108,7 +1115,8 @@ impl<T> [T] { pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> { assert!(chunk_size != 0); let rem = self.len() % chunk_size; - let (fst, snd) = self.split_at_mut(rem); + // SAFETY: 0 <= rem <= self.len() by construction above + let (fst, snd) = unsafe { self.split_at_mut_unchecked(rem) }; RChunksExactMut { v: snd, rem: fst, chunk_size } } @@ -1129,26 +1137,29 @@ impl<T> [T] { /// /// { /// let (left, right) = v.split_at(0); - /// assert!(left == []); - /// assert!(right == [1, 2, 3, 4, 5, 6]); + /// assert_eq!(left, []); + /// assert_eq!(right, [1, 2, 3, 4, 5, 6]); /// } /// /// { /// let (left, right) = v.split_at(2); - /// assert!(left == [1, 2]); - /// assert!(right == [3, 4, 5, 6]); + /// assert_eq!(left, [1, 2]); + /// assert_eq!(right, [3, 4, 5, 6]); /// } /// /// { /// let (left, right) = v.split_at(6); - /// assert!(left == [1, 2, 3, 4, 5, 6]); - /// assert!(right == []); + /// assert_eq!(left, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(right, []); /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn split_at(&self, mid: usize) -> (&[T], &[T]) { - (&self[..mid], &self[mid..]) + assert!(mid <= self.len()); + // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which + // fulfills the requirements of `from_raw_parts_mut`. + unsafe { self.split_at_unchecked(mid) } } /// Divides one mutable slice into two at an index. @@ -1168,26 +1179,115 @@ impl<T> [T] { /// // scoped to restrict the lifetime of the borrows /// { /// let (left, right) = v.split_at_mut(2); - /// assert!(left == [1, 0]); - /// assert!(right == [3, 0, 5, 6]); + /// assert_eq!(left, [1, 0]); + /// assert_eq!(right, [3, 0, 5, 6]); /// left[1] = 2; /// right[1] = 4; /// } - /// assert!(v == [1, 2, 3, 4, 5, 6]); + /// assert_eq!(v, [1, 2, 3, 4, 5, 6]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { - let len = self.len(); - let ptr = self.as_mut_ptr(); - + assert!(mid <= self.len()); // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which // fulfills the requirements of `from_raw_parts_mut`. - unsafe { - assert!(mid <= len); + unsafe { self.split_at_mut_unchecked(mid) } + } - (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) - } + /// Divides one slice into two at an index, without doing bounds checking. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// For a safe alternative see [`split_at`]. + /// + /// # Safety + /// + /// Calling this method with an out-of-bounds index is *[undefined behavior]* + /// even if the resulting reference is not used. The caller has to ensure that + /// `0 <= mid <= self.len()`. + /// + /// [`split_at`]: #method.split_at + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html + /// + /// # Examples + /// + /// ```compile_fail + /// #![feature(slice_split_at_unchecked)] + /// + /// let v = [1, 2, 3, 4, 5, 6]; + /// + /// unsafe { + /// let (left, right) = v.split_at_unchecked(0); + /// assert_eq!(left, []); + /// assert_eq!(right, [1, 2, 3, 4, 5, 6]); + /// } + /// + /// unsafe { + /// let (left, right) = v.split_at_unchecked(2); + /// assert_eq!(left, [1, 2]); + /// assert_eq!(right, [3, 4, 5, 6]); + /// } + /// + /// unsafe { + /// let (left, right) = v.split_at_unchecked(6); + /// assert_eq!(left, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(right, []); + /// } + /// ``` + #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] + #[inline] + unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) { + // SAFETY: Caller has to check that `0 <= mid <= self.len()` + unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) } + } + + /// Divides one mutable slice into two at an index, without doing bounds checking. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// For a safe alternative see [`split_at_mut`]. + /// + /// # Safety + /// + /// Calling this method with an out-of-bounds index is *[undefined behavior]* + /// even if the resulting reference is not used. The caller has to ensure that + /// `0 <= mid <= self.len()`. + /// + /// [`split_at_mut`]: #method.split_at_mut + /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html + /// + /// # Examples + /// + /// ```compile_fail + /// #![feature(slice_split_at_unchecked)] + /// + /// let mut v = [1, 0, 3, 0, 5, 6]; + /// // scoped to restrict the lifetime of the borrows + /// unsafe { + /// let (left, right) = v.split_at_mut_unchecked(2); + /// assert_eq!(left, [1, 0]); + /// assert_eq!(right, [3, 0, 5, 6]); + /// left[1] = 2; + /// right[1] = 4; + /// } + /// assert_eq!(v, [1, 2, 3, 4, 5, 6]); + /// ``` + #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] + #[inline] + unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) { + let len = self.len(); + let ptr = self.as_mut_ptr(); + + // SAFETY: Caller has to check that `0 <= mid <= self.len()`. + // + // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference + // is fine. + unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) } } /// Returns an iterator over subslices separated by elements that match @@ -5390,7 +5490,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { /// This struct is created by the [`chunks_exact`] method on [slices]. /// /// [`chunks_exact`]: ../../std/primitive.slice.html#method.chunks_exact -/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder +/// [`remainder`]: ChunksExact::remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] @@ -5530,7 +5630,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> { /// This struct is created by the [`chunks_exact_mut`] method on [slices]. /// /// [`chunks_exact_mut`]: ../../std/primitive.slice.html#method.chunks_exact_mut -/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder +/// [`into_remainder`]: ChunksExactMut::into_remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] @@ -5667,7 +5767,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { /// This struct is created by the [`array_chunks`] method on [slices]. /// /// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks -/// [`remainder`]: ../../std/slice/struct.ArrayChunks.html#method.remainder +/// [`remainder`]: ArrayChunks::remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[unstable(feature = "array_chunks", issue = "74985")] @@ -6072,7 +6172,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> { /// This struct is created by the [`rchunks_exact`] method on [slices]. /// /// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact -/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder +/// [`remainder`]: ChunksExact::remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] @@ -6217,7 +6317,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> { /// This struct is created by the [`rchunks_exact_mut`] method on [slices]. /// /// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut -/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder +/// [`into_remainder`]: ChunksExactMut::into_remainder /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] @@ -6427,8 +6527,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { /// } /// ``` /// -/// [valid]: ../../std/ptr/index.html#safety -/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling +/// [valid]: ptr#safety +/// [`NonNull::dangling()`]: ptr::NonNull::dangling /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -6467,10 +6567,9 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { /// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. /// See the safety documentation of [`pointer::offset`]. /// -/// [valid]: ../../std/ptr/index.html#safety -/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling +/// [valid]: ptr#safety +/// [`NonNull::dangling()`]: ptr::NonNull::dangling /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset -/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 81e621318e1..4a651e5aa0e 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,5 +1,6 @@ #![feature(alloc_layout_extra)] #![feature(array_chunks)] +#![feature(array_methods)] #![feature(array_map)] #![feature(bool_to_option)] #![feature(bound_cloned)] diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/core/tests/num/flt2dec/mod.rs index ae892e3b0bf..8e95249a79d 100644 --- a/library/core/tests/num/flt2dec/mod.rs +++ b/library/core/tests/num/flt2dec/mod.rs @@ -1,3 +1,4 @@ +use std::mem::MaybeUninit; use std::{fmt, str}; use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded}; @@ -36,20 +37,20 @@ macro_rules! check_shortest { ); ($f:ident($v:expr) => $buf:expr, $exp:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({ - let mut buf = [b'_'; MAX_SIG_DIGITS]; - let (len, k) = $f(&decode_finite($v), &mut buf); - assert!((&buf[..len], k) == ($buf, $exp), - $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k), + let mut buf = [MaybeUninit::new(b'_'); MAX_SIG_DIGITS]; + let (buf, k) = $f(&decode_finite($v), &mut buf); + assert!((buf, k) == ($buf, $exp), + $fmt, actual = (str::from_utf8(buf).unwrap(), k), expected = (str::from_utf8($buf).unwrap(), $exp), $($key = $val),*); }); ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({ - let mut buf = [b'_'; MAX_SIG_DIGITS]; - let (len, k) = $f(&Decoded { $($k: $v),+ }, &mut buf); - assert!((&buf[..len], k) == ($buf, $exp), - $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k), + let mut buf = [MaybeUninit::new(b'_'); MAX_SIG_DIGITS]; + let (buf, k) = $f(&Decoded { $($k: $v),+ }, &mut buf); + assert!((buf, k) == ($buf, $exp), + $fmt, actual = (str::from_utf8(buf).unwrap(), k), expected = (str::from_utf8($buf).unwrap(), $exp), $($key = $val),*); }) @@ -58,9 +59,9 @@ macro_rules! check_shortest { macro_rules! try_exact { ($f:ident($decoded:expr) => $buf:expr, $expected:expr, $expectedk:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({ - let (len, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN); - assert!((&$buf[..len], k) == ($expected, $expectedk), - $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k), + let (buf, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN); + assert!((buf, k) == ($expected, $expectedk), + $fmt, actual = (str::from_utf8(buf).unwrap(), k), expected = (str::from_utf8($expected).unwrap(), $expectedk), $($key = $val),*); }) @@ -69,9 +70,9 @@ macro_rules! try_exact { macro_rules! try_fixed { ($f:ident($decoded:expr) => $buf:expr, $request:expr, $expected:expr, $expectedk:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({ - let (len, k) = $f($decoded, &mut $buf[..], $request); - assert!((&$buf[..len], k) == ($expected, $expectedk), - $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k), + let (buf, k) = $f($decoded, &mut $buf[..], $request); + assert!((buf, k) == ($expected, $expectedk), + $fmt, actual = (str::from_utf8(buf).unwrap(), k), expected = (str::from_utf8($expected).unwrap(), $expectedk), $($key = $val),*); }) @@ -93,10 +94,10 @@ fn ldexp_f64(a: f64, b: i32) -> f64 { fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16) where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { // use a large enough buffer - let mut buf = [b'_'; 1024]; + let mut buf = [MaybeUninit::new(b'_'); 1024]; let mut expected_ = [b'_'; 1024]; let decoded = decode_finite(v); @@ -118,7 +119,7 @@ where // we should always return `100..00` (`i` digits) instead, since that's // what we can came up with `i` digits anyway. `round_up` assumes that // the adjustment to the length is done by caller, which we simply ignore. - if let Some(_) = round_up(&mut expected_, i) { + if let Some(_) = round_up(&mut expected_[..i]) { expectedk_ += 1; } } @@ -193,10 +194,10 @@ impl TestableFloat for f64 { fn check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16) where T: TestableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { // use a large enough buffer - let mut buf = [b'_'; 1024]; + let mut buf = [MaybeUninit::new(b'_'); 1024]; let v: T = TestableFloat::ldexpi(x, e); let decoded = decode_finite(v); @@ -230,7 +231,7 @@ macro_rules! check_exact_one { pub fn f32_shortest_sanity_test<F>(mut f: F) where - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { // 0.0999999940395355224609375 // 0.100000001490116119384765625 @@ -277,7 +278,7 @@ where pub fn f32_exact_sanity_test<F>(mut f: F) where - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { let minf32 = ldexp_f32(1.0, -149); @@ -321,7 +322,7 @@ where pub fn f64_shortest_sanity_test<F>(mut f: F) where - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { // 0.0999999999999999777955395074968691915273... // 0.1000000000000000055511151231257827021181... @@ -387,7 +388,7 @@ where pub fn f64_exact_sanity_test<F>(mut f: F) where - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { let minf64 = ldexp_f64(1.0, -1074); @@ -474,7 +475,7 @@ where pub fn more_shortest_sanity_test<F>(mut f: F) where - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1, exp: 0, inclusive: true} => b"1", 18); @@ -484,10 +485,10 @@ where fn to_string_with_parts<F>(mut f: F) -> String where - F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a>, + F: for<'a> FnMut(&'a mut [MaybeUninit<u8>], &'a mut [MaybeUninit<Part<'a>>]) -> Formatted<'a>, { - let mut buf = [0; 1024]; - let mut parts = [Part::Zero(0); 16]; + let mut buf = [MaybeUninit::new(0); 1024]; + let mut parts = [MaybeUninit::new(Part::Zero(0)); 16]; let formatted = f(&mut buf, &mut parts); let mut ret = vec![0; formatted.len()]; assert_eq!(formatted.write(&mut ret), Some(ret.len())); @@ -496,14 +497,14 @@ where pub fn to_shortest_str_test<F>(mut f_: F) where - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { use core::num::flt2dec::Sign::*; fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { to_string_with_parts(|buf, parts| { to_shortest_str(|d, b| f(d, b), v, sign, frac_digits, buf, parts) @@ -597,14 +598,14 @@ where pub fn to_shortest_exp_str_test<F>(mut f_: F) where - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { use core::num::flt2dec::Sign::*; fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { to_string_with_parts(|buf, parts| { to_shortest_exp_str(|d, b| f(d, b), v, sign, exp_bounds, upper, buf, parts) @@ -716,14 +717,14 @@ where pub fn to_exact_exp_str_test<F>(mut f_: F) where - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { use core::num::flt2dec::Sign::*; fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { to_string_with_parts(|buf, parts| { to_exact_exp_str(|d, b, l| f(d, b, l), v, sign, ndigits, upper, buf, parts) @@ -989,14 +990,14 @@ where pub fn to_exact_fixed_str_test<F>(mut f_: F) where - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { use core::num::flt2dec::Sign::*; fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String where T: DecodableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16), { to_string_with_parts(|buf, parts| { to_exact_fixed_str(|d, b, l| f(d, b, l), v, sign, frac_digits, buf, parts) diff --git a/library/core/tests/num/flt2dec/random.rs b/library/core/tests/num/flt2dec/random.rs index e5656eb204c..57b3dcf8e1e 100644 --- a/library/core/tests/num/flt2dec/random.rs +++ b/library/core/tests/num/flt2dec/random.rs @@ -1,5 +1,6 @@ #![cfg(not(target_arch = "wasm32"))] +use std::mem::MaybeUninit; use std::str; use core::num::flt2dec::strategy::grisu::format_exact_opt; @@ -20,8 +21,8 @@ pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded { fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize) where - F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>, - G: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>, + G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), V: FnMut(usize) -> Decoded, { assert!(k <= 1024); @@ -42,11 +43,11 @@ where } let decoded = v(i); - let mut buf1 = [0; 1024]; - if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) { - let mut buf2 = [0; 1024]; - let (len2, e2) = g(&decoded, &mut buf2[..k]); - if e1 == e2 && &buf1[..len1] == &buf2[..len2] { + let mut buf1 = [MaybeUninit::new(0); 1024]; + if let Some((buf1, e1)) = f(&decoded, &mut buf1[..k]) { + let mut buf2 = [MaybeUninit::new(0); 1024]; + let (buf2, e2) = g(&decoded, &mut buf2[..k]); + if e1 == e2 && buf1 == buf2 { npassed += 1; } else { println!( @@ -54,9 +55,9 @@ where i, n, decoded, - str::from_utf8(&buf1[..len1]).unwrap(), + str::from_utf8(buf1).unwrap(), e1, - str::from_utf8(&buf2[..len2]).unwrap(), + str::from_utf8(buf2).unwrap(), e2 ); } @@ -85,8 +86,8 @@ where pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize) where - F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>, - G: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>, + G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { if cfg!(target_os = "emscripten") { return; // using rng pulls in i128 support, which doesn't work @@ -101,8 +102,8 @@ where pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize) where - F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>, - G: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>, + G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { if cfg!(target_os = "emscripten") { return; // using rng pulls in i128 support, which doesn't work @@ -117,8 +118,8 @@ where pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize) where - F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>, - G: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> Option<(&'a [u8], i16)>, + G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16), { // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values, // so why not simply testing all of them? diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index fa308160fc2..b46bcfd16d2 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -1,4 +1,3 @@ -use core::array::FixedSizeArray; use core::clone::Clone; use core::mem; use core::ops::DerefMut; diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs index caa2d916cd7..35598295a95 100644 --- a/library/core/tests/result.rs +++ b/library/core/tests/result.rs @@ -1,4 +1,3 @@ -use core::array::FixedSizeArray; use core::ops::DerefMut; use core::option::*; diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index c00e07388b8..3d9016293b8 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -311,11 +311,13 @@ impl Bridge<'_> { HIDE_PANICS_DURING_EXPANSION.call_once(|| { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { - let hide = BridgeState::with(|state| match state { - BridgeState::NotConnected => false, - BridgeState::Connected(_) | BridgeState::InUse => true, + let show = BridgeState::with(|state| match state { + BridgeState::NotConnected => true, + // Something weird is going on, so don't suppress any backtraces + BridgeState::InUse => true, + BridgeState::Connected(bridge) => bridge.force_show_panics, }); - if !hide { + if show { prev(info) } })); diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 324be9f4701..c898d483a8b 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -220,6 +220,9 @@ pub struct Bridge<'a> { /// Server-side function that the client uses to make requests. dispatch: closure::Closure<'a, Buffer<u8>, Buffer<u8>>, + + /// If 'true', always invoke the default panic hook + force_show_panics: bool, } impl<'a> !Sync for Bridge<'a> {} diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index eb39025e4c2..1b3ccf4c18e 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -135,6 +135,7 @@ pub trait ExecutionStrategy { input: Buffer<u8>, run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, client_data: D, + force_show_panics: bool, ) -> Buffer<u8>; } @@ -147,10 +148,14 @@ impl ExecutionStrategy for SameThread { input: Buffer<u8>, run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, client_data: D, + force_show_panics: bool, ) -> Buffer<u8> { let mut dispatch = |b| dispatcher.dispatch(b); - run_client(Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, client_data) + run_client( + Bridge { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics }, + client_data, + ) } } @@ -166,6 +171,7 @@ impl ExecutionStrategy for CrossThread1 { input: Buffer<u8>, run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, client_data: D, + force_show_panics: bool, ) -> Buffer<u8> { use std::sync::mpsc::channel; @@ -179,7 +185,11 @@ impl ExecutionStrategy for CrossThread1 { }; run_client( - Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, + Bridge { + cached_buffer: input, + dispatch: (&mut dispatch).into(), + force_show_panics, + }, client_data, ) }); @@ -201,6 +211,7 @@ impl ExecutionStrategy for CrossThread2 { input: Buffer<u8>, run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, client_data: D, + force_show_panics: bool, ) -> Buffer<u8> { use std::sync::{Arc, Mutex}; @@ -226,7 +237,11 @@ impl ExecutionStrategy for CrossThread2 { }; let r = run_client( - Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, + Bridge { + cached_buffer: input, + dispatch: (&mut dispatch).into(), + force_show_panics, + }, client_data, ); @@ -265,6 +280,7 @@ fn run_server< input: I, run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, client_data: D, + force_show_panics: bool, ) -> Result<O, PanicMessage> { let mut dispatcher = Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) }; @@ -272,7 +288,13 @@ fn run_server< let mut b = Buffer::new(); input.encode(&mut b, &mut dispatcher.handle_store); - b = strategy.run_bridge_and_client(&mut dispatcher, b, run_client, client_data); + b = strategy.run_bridge_and_client( + &mut dispatcher, + b, + run_client, + client_data, + force_show_panics, + ); Result::decode(&mut &b[..], &mut dispatcher.handle_store) } @@ -283,6 +305,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> { strategy: &impl ExecutionStrategy, server: S, input: S::TokenStream, + force_show_panics: bool, ) -> Result<S::TokenStream, PanicMessage> { let client::Client { get_handle_counters, run, f } = *self; run_server( @@ -292,6 +315,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> { <MarkedTypes<S> as Types>::TokenStream::mark(input), run, f, + force_show_panics, ) .map(<MarkedTypes<S> as Types>::TokenStream::unmark) } @@ -304,6 +328,7 @@ impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenSt server: S, input: S::TokenStream, input2: S::TokenStream, + force_show_panics: bool, ) -> Result<S::TokenStream, PanicMessage> { let client::Client { get_handle_counters, run, f } = *self; run_server( @@ -316,6 +341,7 @@ impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenSt ), run, f, + force_show_panics, ) .map(<MarkedTypes<S> as Types>::TokenStream::unmark) } diff --git a/library/std/src/ascii.rs b/library/std/src/ascii.rs index c9106136d34..035cd9f243b 100644 --- a/library/std/src/ascii.rs +++ b/library/std/src/ascii.rs @@ -70,7 +70,6 @@ pub trait AsciiExt { /// inherent methods on `u8`, `char`, `[u8]` and `str`. /// /// [`make_ascii_uppercase`]: AsciiExt::make_ascii_uppercase - /// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] fn to_ascii_uppercase(&self) -> Self::Owned; @@ -91,7 +90,6 @@ pub trait AsciiExt { /// inherent methods on `u8`, `char`, `[u8]` and `str`. /// /// [`make_ascii_lowercase`]: AsciiExt::make_ascii_lowercase - /// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] fn to_ascii_lowercase(&self) -> Self::Owned; diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 09f83ea5fca..cc29e1c0b05 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -66,6 +66,9 @@ #![unstable(feature = "backtrace", issue = "53487")] +#[cfg(test)] +mod tests; + // NB: A note on resolution of a backtrace: // // Backtraces primarily happen in two steps, one is where we actually capture @@ -438,55 +441,3 @@ impl RawFrame { } } } - -#[test] -fn test_debug() { - let backtrace = Backtrace { - inner: Inner::Captured(Mutex::new(Capture { - actual_start: 1, - resolved: true, - frames: vec![ - BacktraceFrame { - frame: RawFrame::Fake, - symbols: vec![BacktraceSymbol { - name: Some(b"std::backtrace::Backtrace::create".to_vec()), - filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())), - lineno: Some(100), - }], - }, - BacktraceFrame { - frame: RawFrame::Fake, - symbols: vec![BacktraceSymbol { - name: Some(b"__rust_maybe_catch_panic".to_vec()), - filename: None, - lineno: None, - }], - }, - BacktraceFrame { - frame: RawFrame::Fake, - symbols: vec![ - BacktraceSymbol { - name: Some(b"std::rt::lang_start_internal".to_vec()), - filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())), - lineno: Some(300), - }, - BacktraceSymbol { - name: Some(b"std::rt::lang_start".to_vec()), - filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())), - lineno: Some(400), - }, - ], - }, - ], - })), - }; - - #[rustfmt::skip] - let expected = "Backtrace [\ - \n { fn: \"__rust_maybe_catch_panic\" },\ - \n { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\ - \n { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\ - \n]"; - - assert_eq!(format!("{:#?}", backtrace), expected); -} diff --git a/library/std/src/backtrace/tests.rs b/library/std/src/backtrace/tests.rs new file mode 100644 index 00000000000..287359cd545 --- /dev/null +++ b/library/std/src/backtrace/tests.rs @@ -0,0 +1,53 @@ +use super::*; + +#[test] +fn test_debug() { + let backtrace = Backtrace { + inner: Inner::Captured(Mutex::new(Capture { + actual_start: 1, + resolved: true, + frames: vec![ + BacktraceFrame { + frame: RawFrame::Fake, + symbols: vec![BacktraceSymbol { + name: Some(b"std::backtrace::Backtrace::create".to_vec()), + filename: Some(BytesOrWide::Bytes(b"rust/backtrace.rs".to_vec())), + lineno: Some(100), + }], + }, + BacktraceFrame { + frame: RawFrame::Fake, + symbols: vec![BacktraceSymbol { + name: Some(b"__rust_maybe_catch_panic".to_vec()), + filename: None, + lineno: None, + }], + }, + BacktraceFrame { + frame: RawFrame::Fake, + symbols: vec![ + BacktraceSymbol { + name: Some(b"std::rt::lang_start_internal".to_vec()), + filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())), + lineno: Some(300), + }, + BacktraceSymbol { + name: Some(b"std::rt::lang_start".to_vec()), + filename: Some(BytesOrWide::Bytes(b"rust/rt.rs".to_vec())), + lineno: Some(400), + }, + ], + }, + ], + })), + }; + + #[rustfmt::skip] + let expected = "Backtrace [\ + \n { fn: \"__rust_maybe_catch_panic\" },\ + \n { fn: \"std::rt::lang_start_internal\", file: \"rust/rt.rs\", line: 300 },\ + \n { fn: \"std::rt::lang_start\", file: \"rust/rt.rs\", line: 400 },\ + \n]"; + + assert_eq!(format!("{:#?}", backtrace), expected); +} diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 70f7214e2f1..77cc5b93dbb 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1,4 +1,5 @@ -// ignore-tidy-filelength +#[cfg(test)] +mod tests; use self::Entry::*; @@ -2754,933 +2755,3 @@ fn assert_covariance() { d } } - -#[cfg(test)] -mod test_map { - use super::Entry::{Occupied, Vacant}; - use super::HashMap; - use super::RandomState; - use crate::cell::RefCell; - use rand::{thread_rng, Rng}; - use realstd::collections::TryReserveError::*; - - // https://github.com/rust-lang/rust/issues/62301 - fn _assert_hashmap_is_unwind_safe() { - fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {} - assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>(); - } - - #[test] - fn test_zero_capacities() { - type HM = HashMap<i32, i32>; - - let m = HM::new(); - assert_eq!(m.capacity(), 0); - - let m = HM::default(); - assert_eq!(m.capacity(), 0); - - let m = HM::with_hasher(RandomState::new()); - assert_eq!(m.capacity(), 0); - - let m = HM::with_capacity(0); - assert_eq!(m.capacity(), 0); - - let m = HM::with_capacity_and_hasher(0, RandomState::new()); - assert_eq!(m.capacity(), 0); - - let mut m = HM::new(); - m.insert(1, 1); - m.insert(2, 2); - m.remove(&1); - m.remove(&2); - m.shrink_to_fit(); - assert_eq!(m.capacity(), 0); - - let mut m = HM::new(); - m.reserve(0); - assert_eq!(m.capacity(), 0); - } - - #[test] - fn test_create_capacity_zero() { - let mut m = HashMap::with_capacity(0); - - assert!(m.insert(1, 1).is_none()); - - assert!(m.contains_key(&1)); - assert!(!m.contains_key(&0)); - } - - #[test] - fn test_insert() { - let mut m = HashMap::new(); - assert_eq!(m.len(), 0); - assert!(m.insert(1, 2).is_none()); - assert_eq!(m.len(), 1); - assert!(m.insert(2, 4).is_none()); - assert_eq!(m.len(), 2); - assert_eq!(*m.get(&1).unwrap(), 2); - assert_eq!(*m.get(&2).unwrap(), 4); - } - - #[test] - fn test_clone() { - let mut m = HashMap::new(); - assert_eq!(m.len(), 0); - assert!(m.insert(1, 2).is_none()); - assert_eq!(m.len(), 1); - assert!(m.insert(2, 4).is_none()); - assert_eq!(m.len(), 2); - let m2 = m.clone(); - assert_eq!(*m2.get(&1).unwrap(), 2); - assert_eq!(*m2.get(&2).unwrap(), 4); - assert_eq!(m2.len(), 2); - } - - thread_local! { static DROP_VECTOR: RefCell<Vec<i32>> = RefCell::new(Vec::new()) } - - #[derive(Hash, PartialEq, Eq)] - struct Droppable { - k: usize, - } - - impl Droppable { - fn new(k: usize) -> Droppable { - DROP_VECTOR.with(|slot| { - slot.borrow_mut()[k] += 1; - }); - - Droppable { k } - } - } - - impl Drop for Droppable { - fn drop(&mut self) { - DROP_VECTOR.with(|slot| { - slot.borrow_mut()[self.k] -= 1; - }); - } - } - - impl Clone for Droppable { - fn clone(&self) -> Droppable { - Droppable::new(self.k) - } - } - - #[test] - fn test_drops() { - DROP_VECTOR.with(|slot| { - *slot.borrow_mut() = vec![0; 200]; - }); - - { - let mut m = HashMap::new(); - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 0); - } - }); - - for i in 0..100 { - let d1 = Droppable::new(i); - let d2 = Droppable::new(i + 100); - m.insert(d1, d2); - } - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 1); - } - }); - - for i in 0..50 { - let k = Droppable::new(i); - let v = m.remove(&k); - - assert!(v.is_some()); - - DROP_VECTOR.with(|v| { - assert_eq!(v.borrow()[i], 1); - assert_eq!(v.borrow()[i + 100], 1); - }); - } - - DROP_VECTOR.with(|v| { - for i in 0..50 { - assert_eq!(v.borrow()[i], 0); - assert_eq!(v.borrow()[i + 100], 0); - } - - for i in 50..100 { - assert_eq!(v.borrow()[i], 1); - assert_eq!(v.borrow()[i + 100], 1); - } - }); - } - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 0); - } - }); - } - - #[test] - fn test_into_iter_drops() { - DROP_VECTOR.with(|v| { - *v.borrow_mut() = vec![0; 200]; - }); - - let hm = { - let mut hm = HashMap::new(); - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 0); - } - }); - - for i in 0..100 { - let d1 = Droppable::new(i); - let d2 = Droppable::new(i + 100); - hm.insert(d1, d2); - } - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 1); - } - }); - - hm - }; - - // By the way, ensure that cloning doesn't screw up the dropping. - drop(hm.clone()); - - { - let mut half = hm.into_iter().take(50); - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 1); - } - }); - - for _ in half.by_ref() {} - - DROP_VECTOR.with(|v| { - let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count(); - - let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count(); - - assert_eq!(nk, 50); - assert_eq!(nv, 50); - }); - }; - - DROP_VECTOR.with(|v| { - for i in 0..200 { - assert_eq!(v.borrow()[i], 0); - } - }); - } - - #[test] - fn test_empty_remove() { - let mut m: HashMap<i32, bool> = HashMap::new(); - assert_eq!(m.remove(&0), None); - } - - #[test] - fn test_empty_entry() { - let mut m: HashMap<i32, bool> = HashMap::new(); - match m.entry(0) { - Occupied(_) => panic!(), - Vacant(_) => {} - } - assert!(*m.entry(0).or_insert(true)); - assert_eq!(m.len(), 1); - } - - #[test] - fn test_empty_iter() { - let mut m: HashMap<i32, bool> = HashMap::new(); - assert_eq!(m.drain().next(), None); - assert_eq!(m.keys().next(), None); - assert_eq!(m.values().next(), None); - assert_eq!(m.values_mut().next(), None); - assert_eq!(m.iter().next(), None); - assert_eq!(m.iter_mut().next(), None); - assert_eq!(m.len(), 0); - assert!(m.is_empty()); - assert_eq!(m.into_iter().next(), None); - } - - #[test] - fn test_lots_of_insertions() { - let mut m = HashMap::new(); - - // Try this a few times to make sure we never screw up the hashmap's - // internal state. - for _ in 0..10 { - assert!(m.is_empty()); - - for i in 1..1001 { - assert!(m.insert(i, i).is_none()); - - for j in 1..=i { - let r = m.get(&j); - assert_eq!(r, Some(&j)); - } - - for j in i + 1..1001 { - let r = m.get(&j); - assert_eq!(r, None); - } - } - - for i in 1001..2001 { - assert!(!m.contains_key(&i)); - } - - // remove forwards - for i in 1..1001 { - assert!(m.remove(&i).is_some()); - - for j in 1..=i { - assert!(!m.contains_key(&j)); - } - - for j in i + 1..1001 { - assert!(m.contains_key(&j)); - } - } - - for i in 1..1001 { - assert!(!m.contains_key(&i)); - } - - for i in 1..1001 { - assert!(m.insert(i, i).is_none()); - } - - // remove backwards - for i in (1..1001).rev() { - assert!(m.remove(&i).is_some()); - - for j in i..1001 { - assert!(!m.contains_key(&j)); - } - - for j in 1..i { - assert!(m.contains_key(&j)); - } - } - } - } - - #[test] - fn test_find_mut() { - let mut m = HashMap::new(); - assert!(m.insert(1, 12).is_none()); - assert!(m.insert(2, 8).is_none()); - assert!(m.insert(5, 14).is_none()); - let new = 100; - match m.get_mut(&5) { - None => panic!(), - Some(x) => *x = new, - } - assert_eq!(m.get(&5), Some(&new)); - } - - #[test] - fn test_insert_overwrite() { - let mut m = HashMap::new(); - assert!(m.insert(1, 2).is_none()); - assert_eq!(*m.get(&1).unwrap(), 2); - assert!(!m.insert(1, 3).is_none()); - assert_eq!(*m.get(&1).unwrap(), 3); - } - - #[test] - fn test_insert_conflicts() { - let mut m = HashMap::with_capacity(4); - assert!(m.insert(1, 2).is_none()); - assert!(m.insert(5, 3).is_none()); - assert!(m.insert(9, 4).is_none()); - assert_eq!(*m.get(&9).unwrap(), 4); - assert_eq!(*m.get(&5).unwrap(), 3); - assert_eq!(*m.get(&1).unwrap(), 2); - } - - #[test] - fn test_conflict_remove() { - let mut m = HashMap::with_capacity(4); - assert!(m.insert(1, 2).is_none()); - assert_eq!(*m.get(&1).unwrap(), 2); - assert!(m.insert(5, 3).is_none()); - assert_eq!(*m.get(&1).unwrap(), 2); - assert_eq!(*m.get(&5).unwrap(), 3); - assert!(m.insert(9, 4).is_none()); - assert_eq!(*m.get(&1).unwrap(), 2); - assert_eq!(*m.get(&5).unwrap(), 3); - assert_eq!(*m.get(&9).unwrap(), 4); - assert!(m.remove(&1).is_some()); - assert_eq!(*m.get(&9).unwrap(), 4); - assert_eq!(*m.get(&5).unwrap(), 3); - } - - #[test] - fn test_is_empty() { - let mut m = HashMap::with_capacity(4); - assert!(m.insert(1, 2).is_none()); - assert!(!m.is_empty()); - assert!(m.remove(&1).is_some()); - assert!(m.is_empty()); - } - - #[test] - fn test_remove() { - let mut m = HashMap::new(); - m.insert(1, 2); - assert_eq!(m.remove(&1), Some(2)); - assert_eq!(m.remove(&1), None); - } - - #[test] - fn test_remove_entry() { - let mut m = HashMap::new(); - m.insert(1, 2); - assert_eq!(m.remove_entry(&1), Some((1, 2))); - assert_eq!(m.remove(&1), None); - } - - #[test] - fn test_iterate() { - let mut m = HashMap::with_capacity(4); - for i in 0..32 { - assert!(m.insert(i, i * 2).is_none()); - } - assert_eq!(m.len(), 32); - - let mut observed: u32 = 0; - - for (k, v) in &m { - assert_eq!(*v, *k * 2); - observed |= 1 << *k; - } - assert_eq!(observed, 0xFFFF_FFFF); - } - - #[test] - fn test_keys() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: HashMap<_, _> = vec.into_iter().collect(); - let keys: Vec<_> = map.keys().cloned().collect(); - assert_eq!(keys.len(), 3); - assert!(keys.contains(&1)); - assert!(keys.contains(&2)); - assert!(keys.contains(&3)); - } - - #[test] - fn test_values() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: HashMap<_, _> = vec.into_iter().collect(); - let values: Vec<_> = map.values().cloned().collect(); - assert_eq!(values.len(), 3); - assert!(values.contains(&'a')); - assert!(values.contains(&'b')); - assert!(values.contains(&'c')); - } - - #[test] - fn test_values_mut() { - let vec = vec![(1, 1), (2, 2), (3, 3)]; - let mut map: HashMap<_, _> = vec.into_iter().collect(); - for value in map.values_mut() { - *value = (*value) * 2 - } - let values: Vec<_> = map.values().cloned().collect(); - assert_eq!(values.len(), 3); - assert!(values.contains(&2)); - assert!(values.contains(&4)); - assert!(values.contains(&6)); - } - - #[test] - fn test_into_keys() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: HashMap<_, _> = vec.into_iter().collect(); - let keys: Vec<_> = map.into_keys().collect(); - - assert_eq!(keys.len(), 3); - assert!(keys.contains(&1)); - assert!(keys.contains(&2)); - assert!(keys.contains(&3)); - } - - #[test] - fn test_into_values() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map: HashMap<_, _> = vec.into_iter().collect(); - let values: Vec<_> = map.into_values().collect(); - - assert_eq!(values.len(), 3); - assert!(values.contains(&'a')); - assert!(values.contains(&'b')); - assert!(values.contains(&'c')); - } - - #[test] - fn test_find() { - let mut m = HashMap::new(); - assert!(m.get(&1).is_none()); - m.insert(1, 2); - match m.get(&1) { - None => panic!(), - Some(v) => assert_eq!(*v, 2), - } - } - - #[test] - fn test_eq() { - let mut m1 = HashMap::new(); - m1.insert(1, 2); - m1.insert(2, 3); - m1.insert(3, 4); - - let mut m2 = HashMap::new(); - m2.insert(1, 2); - m2.insert(2, 3); - - assert!(m1 != m2); - - m2.insert(3, 4); - - assert_eq!(m1, m2); - } - - #[test] - fn test_show() { - let mut map = HashMap::new(); - let empty: HashMap<i32, i32> = HashMap::new(); - - map.insert(1, 2); - map.insert(3, 4); - - let map_str = format!("{:?}", map); - - assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); - assert_eq!(format!("{:?}", empty), "{}"); - } - - #[test] - fn test_reserve_shrink_to_fit() { - let mut m = HashMap::new(); - m.insert(0, 0); - m.remove(&0); - assert!(m.capacity() >= m.len()); - for i in 0..128 { - m.insert(i, i); - } - m.reserve(256); - - let usable_cap = m.capacity(); - for i in 128..(128 + 256) { - m.insert(i, i); - assert_eq!(m.capacity(), usable_cap); - } - - for i in 100..(128 + 256) { - assert_eq!(m.remove(&i), Some(i)); - } - m.shrink_to_fit(); - - assert_eq!(m.len(), 100); - assert!(!m.is_empty()); - assert!(m.capacity() >= m.len()); - - for i in 0..100 { - assert_eq!(m.remove(&i), Some(i)); - } - m.shrink_to_fit(); - m.insert(0, 0); - - assert_eq!(m.len(), 1); - assert!(m.capacity() >= m.len()); - assert_eq!(m.remove(&0), Some(0)); - } - - #[test] - fn test_from_iter() { - let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let map: HashMap<_, _> = xs.iter().cloned().collect(); - - for &(k, v) in &xs { - assert_eq!(map.get(&k), Some(&v)); - } - - assert_eq!(map.iter().len(), xs.len() - 1); - } - - #[test] - fn test_size_hint() { - let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let map: HashMap<_, _> = xs.iter().cloned().collect(); - - let mut iter = map.iter(); - - for _ in iter.by_ref().take(3) {} - - assert_eq!(iter.size_hint(), (3, Some(3))); - } - - #[test] - fn test_iter_len() { - let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let map: HashMap<_, _> = xs.iter().cloned().collect(); - - let mut iter = map.iter(); - - for _ in iter.by_ref().take(3) {} - - assert_eq!(iter.len(), 3); - } - - #[test] - fn test_mut_size_hint() { - let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let mut map: HashMap<_, _> = xs.iter().cloned().collect(); - - let mut iter = map.iter_mut(); - - for _ in iter.by_ref().take(3) {} - - assert_eq!(iter.size_hint(), (3, Some(3))); - } - - #[test] - fn test_iter_mut_len() { - let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let mut map: HashMap<_, _> = xs.iter().cloned().collect(); - - let mut iter = map.iter_mut(); - - for _ in iter.by_ref().take(3) {} - - assert_eq!(iter.len(), 3); - } - - #[test] - fn test_index() { - let mut map = HashMap::new(); - - map.insert(1, 2); - map.insert(2, 1); - map.insert(3, 4); - - assert_eq!(map[&2], 1); - } - - #[test] - #[should_panic] - fn test_index_nonexistent() { - let mut map = HashMap::new(); - - map.insert(1, 2); - map.insert(2, 1); - map.insert(3, 4); - - map[&4]; - } - - #[test] - fn test_entry() { - let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; - - let mut map: HashMap<_, _> = xs.iter().cloned().collect(); - - // Existing key (insert) - match map.entry(1) { - Vacant(_) => unreachable!(), - Occupied(mut view) => { - assert_eq!(view.get(), &10); - assert_eq!(view.insert(100), 10); - } - } - assert_eq!(map.get(&1).unwrap(), &100); - assert_eq!(map.len(), 6); - - // Existing key (update) - match map.entry(2) { - Vacant(_) => unreachable!(), - Occupied(mut view) => { - let v = view.get_mut(); - let new_v = (*v) * 10; - *v = new_v; - } - } - assert_eq!(map.get(&2).unwrap(), &200); - assert_eq!(map.len(), 6); - - // Existing key (take) - match map.entry(3) { - Vacant(_) => unreachable!(), - Occupied(view) => { - assert_eq!(view.remove(), 30); - } - } - assert_eq!(map.get(&3), None); - assert_eq!(map.len(), 5); - - // Inexistent key (insert) - match map.entry(10) { - Occupied(_) => unreachable!(), - Vacant(view) => { - assert_eq!(*view.insert(1000), 1000); - } - } - assert_eq!(map.get(&10).unwrap(), &1000); - assert_eq!(map.len(), 6); - } - - #[test] - fn test_entry_take_doesnt_corrupt() { - #![allow(deprecated)] //rand - // Test for #19292 - fn check(m: &HashMap<i32, ()>) { - for k in m.keys() { - assert!(m.contains_key(k), "{} is in keys() but not in the map?", k); - } - } - - let mut m = HashMap::new(); - let mut rng = thread_rng(); - - // Populate the map with some items. - for _ in 0..50 { - let x = rng.gen_range(-10, 10); - m.insert(x, ()); - } - - for _ in 0..1000 { - let x = rng.gen_range(-10, 10); - match m.entry(x) { - Vacant(_) => {} - Occupied(e) => { - e.remove(); - } - } - - check(&m); - } - } - - #[test] - fn test_extend_ref() { - let mut a = HashMap::new(); - a.insert(1, "one"); - let mut b = HashMap::new(); - b.insert(2, "two"); - b.insert(3, "three"); - - a.extend(&b); - - assert_eq!(a.len(), 3); - assert_eq!(a[&1], "one"); - assert_eq!(a[&2], "two"); - assert_eq!(a[&3], "three"); - } - - #[test] - fn test_capacity_not_less_than_len() { - let mut a = HashMap::new(); - let mut item = 0; - - for _ in 0..116 { - a.insert(item, 0); - item += 1; - } - - assert!(a.capacity() > a.len()); - - let free = a.capacity() - a.len(); - for _ in 0..free { - a.insert(item, 0); - item += 1; - } - - assert_eq!(a.len(), a.capacity()); - - // Insert at capacity should cause allocation. - a.insert(item, 0); - assert!(a.capacity() > a.len()); - } - - #[test] - fn test_occupied_entry_key() { - let mut a = HashMap::new(); - let key = "hello there"; - let value = "value goes here"; - assert!(a.is_empty()); - a.insert(key.clone(), value.clone()); - assert_eq!(a.len(), 1); - assert_eq!(a[key], value); - - match a.entry(key.clone()) { - Vacant(_) => panic!(), - Occupied(e) => assert_eq!(key, *e.key()), - } - assert_eq!(a.len(), 1); - assert_eq!(a[key], value); - } - - #[test] - fn test_vacant_entry_key() { - let mut a = HashMap::new(); - let key = "hello there"; - let value = "value goes here"; - - assert!(a.is_empty()); - match a.entry(key.clone()) { - Occupied(_) => panic!(), - Vacant(e) => { - assert_eq!(key, *e.key()); - e.insert(value.clone()); - } - } - assert_eq!(a.len(), 1); - assert_eq!(a[key], value); - } - - #[test] - fn test_retain() { - let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect(); - - map.retain(|&k, _| k % 2 == 0); - assert_eq!(map.len(), 50); - assert_eq!(map[&2], 20); - assert_eq!(map[&4], 40); - assert_eq!(map[&6], 60); - } - - #[test] - fn test_try_reserve() { - let mut empty_bytes: HashMap<u8, u8> = HashMap::new(); - - const MAX_USIZE: usize = usize::MAX; - - if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) { - } else { - panic!("usize::MAX should trigger an overflow!"); - } - - if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) { - } else { - panic!("usize::MAX / 8 should trigger an OOM!") - } - } - - #[test] - fn test_raw_entry() { - use super::RawEntryMut::{Occupied, Vacant}; - - let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; - - let mut map: HashMap<_, _> = xs.iter().cloned().collect(); - - let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 { - use core::hash::{BuildHasher, Hash, Hasher}; - - let mut hasher = map.hasher().build_hasher(); - k.hash(&mut hasher); - hasher.finish() - }; - - // Existing key (insert) - match map.raw_entry_mut().from_key(&1) { - Vacant(_) => unreachable!(), - Occupied(mut view) => { - assert_eq!(view.get(), &10); - assert_eq!(view.insert(100), 10); - } - } - let hash1 = compute_hash(&map, 1); - assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100)); - assert_eq!(map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(), (&1, &100)); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(), (&1, &100)); - assert_eq!(map.len(), 6); - - // Existing key (update) - match map.raw_entry_mut().from_key(&2) { - Vacant(_) => unreachable!(), - Occupied(mut view) => { - let v = view.get_mut(); - let new_v = (*v) * 10; - *v = new_v; - } - } - let hash2 = compute_hash(&map, 2); - assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200)); - assert_eq!(map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(), (&2, &200)); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(), (&2, &200)); - assert_eq!(map.len(), 6); - - // Existing key (take) - let hash3 = compute_hash(&map, 3); - match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) { - Vacant(_) => unreachable!(), - Occupied(view) => { - assert_eq!(view.remove_entry(), (3, 30)); - } - } - assert_eq!(map.raw_entry().from_key(&3), None); - assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None); - assert_eq!(map.len(), 5); - - // Nonexistent key (insert) - match map.raw_entry_mut().from_key(&10) { - Occupied(_) => unreachable!(), - Vacant(view) => { - assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000)); - } - } - assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000)); - assert_eq!(map.len(), 6); - - // Ensure all lookup methods produce equivalent results. - for k in 0..12 { - let hash = compute_hash(&map, k); - let v = map.get(&k).cloned(); - let kv = v.as_ref().map(|v| (&k, v)); - - assert_eq!(map.raw_entry().from_key(&k), kv); - assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv); - assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv); - - match map.raw_entry_mut().from_key(&k) { - Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), - Vacant(_) => assert_eq!(v, None), - } - match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) { - Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), - Vacant(_) => assert_eq!(v, None), - } - match map.raw_entry_mut().from_hash(hash, |q| *q == k) { - Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), - Vacant(_) => assert_eq!(v, None), - } - } - } -} diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs new file mode 100644 index 00000000000..4283d80b78e --- /dev/null +++ b/library/std/src/collections/hash/map/tests.rs @@ -0,0 +1,926 @@ +use super::Entry::{Occupied, Vacant}; +use super::HashMap; +use super::RandomState; +use crate::cell::RefCell; +use rand::{thread_rng, Rng}; +use realstd::collections::TryReserveError::*; + +// https://github.com/rust-lang/rust/issues/62301 +fn _assert_hashmap_is_unwind_safe() { + fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {} + assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>(); +} + +#[test] +fn test_zero_capacities() { + type HM = HashMap<i32, i32>; + + let m = HM::new(); + assert_eq!(m.capacity(), 0); + + let m = HM::default(); + assert_eq!(m.capacity(), 0); + + let m = HM::with_hasher(RandomState::new()); + assert_eq!(m.capacity(), 0); + + let m = HM::with_capacity(0); + assert_eq!(m.capacity(), 0); + + let m = HM::with_capacity_and_hasher(0, RandomState::new()); + assert_eq!(m.capacity(), 0); + + let mut m = HM::new(); + m.insert(1, 1); + m.insert(2, 2); + m.remove(&1); + m.remove(&2); + m.shrink_to_fit(); + assert_eq!(m.capacity(), 0); + + let mut m = HM::new(); + m.reserve(0); + assert_eq!(m.capacity(), 0); +} + +#[test] +fn test_create_capacity_zero() { + let mut m = HashMap::with_capacity(0); + + assert!(m.insert(1, 1).is_none()); + + assert!(m.contains_key(&1)); + assert!(!m.contains_key(&0)); +} + +#[test] +fn test_insert() { + let mut m = HashMap::new(); + assert_eq!(m.len(), 0); + assert!(m.insert(1, 2).is_none()); + assert_eq!(m.len(), 1); + assert!(m.insert(2, 4).is_none()); + assert_eq!(m.len(), 2); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&2).unwrap(), 4); +} + +#[test] +fn test_clone() { + let mut m = HashMap::new(); + assert_eq!(m.len(), 0); + assert!(m.insert(1, 2).is_none()); + assert_eq!(m.len(), 1); + assert!(m.insert(2, 4).is_none()); + assert_eq!(m.len(), 2); + let m2 = m.clone(); + assert_eq!(*m2.get(&1).unwrap(), 2); + assert_eq!(*m2.get(&2).unwrap(), 4); + assert_eq!(m2.len(), 2); +} + +thread_local! { static DROP_VECTOR: RefCell<Vec<i32>> = RefCell::new(Vec::new()) } + +#[derive(Hash, PartialEq, Eq)] +struct Droppable { + k: usize, +} + +impl Droppable { + fn new(k: usize) -> Droppable { + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[k] += 1; + }); + + Droppable { k } + } +} + +impl Drop for Droppable { + fn drop(&mut self) { + DROP_VECTOR.with(|slot| { + slot.borrow_mut()[self.k] -= 1; + }); + } +} + +impl Clone for Droppable { + fn clone(&self) -> Droppable { + Droppable::new(self.k) + } +} + +#[test] +fn test_drops() { + DROP_VECTOR.with(|slot| { + *slot.borrow_mut() = vec![0; 200]; + }); + + { + let mut m = HashMap::new(); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + + for i in 0..100 { + let d1 = Droppable::new(i); + let d2 = Droppable::new(i + 100); + m.insert(d1, d2); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + for i in 0..50 { + let k = Droppable::new(i); + let v = m.remove(&k); + + assert!(v.is_some()); + + DROP_VECTOR.with(|v| { + assert_eq!(v.borrow()[i], 1); + assert_eq!(v.borrow()[i + 100], 1); + }); + } + + DROP_VECTOR.with(|v| { + for i in 0..50 { + assert_eq!(v.borrow()[i], 0); + assert_eq!(v.borrow()[i + 100], 0); + } + + for i in 50..100 { + assert_eq!(v.borrow()[i], 1); + assert_eq!(v.borrow()[i + 100], 1); + } + }); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); +} + +#[test] +fn test_into_iter_drops() { + DROP_VECTOR.with(|v| { + *v.borrow_mut() = vec![0; 200]; + }); + + let hm = { + let mut hm = HashMap::new(); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); + + for i in 0..100 { + let d1 = Droppable::new(i); + let d2 = Droppable::new(i + 100); + hm.insert(d1, d2); + } + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + hm + }; + + // By the way, ensure that cloning doesn't screw up the dropping. + drop(hm.clone()); + + { + let mut half = hm.into_iter().take(50); + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 1); + } + }); + + for _ in half.by_ref() {} + + DROP_VECTOR.with(|v| { + let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count(); + + let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count(); + + assert_eq!(nk, 50); + assert_eq!(nv, 50); + }); + }; + + DROP_VECTOR.with(|v| { + for i in 0..200 { + assert_eq!(v.borrow()[i], 0); + } + }); +} + +#[test] +fn test_empty_remove() { + let mut m: HashMap<i32, bool> = HashMap::new(); + assert_eq!(m.remove(&0), None); +} + +#[test] +fn test_empty_entry() { + let mut m: HashMap<i32, bool> = HashMap::new(); + match m.entry(0) { + Occupied(_) => panic!(), + Vacant(_) => {} + } + assert!(*m.entry(0).or_insert(true)); + assert_eq!(m.len(), 1); +} + +#[test] +fn test_empty_iter() { + let mut m: HashMap<i32, bool> = HashMap::new(); + assert_eq!(m.drain().next(), None); + assert_eq!(m.keys().next(), None); + assert_eq!(m.values().next(), None); + assert_eq!(m.values_mut().next(), None); + assert_eq!(m.iter().next(), None); + assert_eq!(m.iter_mut().next(), None); + assert_eq!(m.len(), 0); + assert!(m.is_empty()); + assert_eq!(m.into_iter().next(), None); +} + +#[test] +fn test_lots_of_insertions() { + let mut m = HashMap::new(); + + // Try this a few times to make sure we never screw up the hashmap's + // internal state. + for _ in 0..10 { + assert!(m.is_empty()); + + for i in 1..1001 { + assert!(m.insert(i, i).is_none()); + + for j in 1..=i { + let r = m.get(&j); + assert_eq!(r, Some(&j)); + } + + for j in i + 1..1001 { + let r = m.get(&j); + assert_eq!(r, None); + } + } + + for i in 1001..2001 { + assert!(!m.contains_key(&i)); + } + + // remove forwards + for i in 1..1001 { + assert!(m.remove(&i).is_some()); + + for j in 1..=i { + assert!(!m.contains_key(&j)); + } + + for j in i + 1..1001 { + assert!(m.contains_key(&j)); + } + } + + for i in 1..1001 { + assert!(!m.contains_key(&i)); + } + + for i in 1..1001 { + assert!(m.insert(i, i).is_none()); + } + + // remove backwards + for i in (1..1001).rev() { + assert!(m.remove(&i).is_some()); + + for j in i..1001 { + assert!(!m.contains_key(&j)); + } + + for j in 1..i { + assert!(m.contains_key(&j)); + } + } + } +} + +#[test] +fn test_find_mut() { + let mut m = HashMap::new(); + assert!(m.insert(1, 12).is_none()); + assert!(m.insert(2, 8).is_none()); + assert!(m.insert(5, 14).is_none()); + let new = 100; + match m.get_mut(&5) { + None => panic!(), + Some(x) => *x = new, + } + assert_eq!(m.get(&5), Some(&new)); +} + +#[test] +fn test_insert_overwrite() { + let mut m = HashMap::new(); + assert!(m.insert(1, 2).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(!m.insert(1, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 3); +} + +#[test] +fn test_insert_conflicts() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(5, 3).is_none()); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&1).unwrap(), 2); +} + +#[test] +fn test_conflict_remove() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(m.insert(5, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&9).unwrap(), 4); + assert!(m.remove(&1).is_some()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); +} + +#[test] +fn test_is_empty() { + let mut m = HashMap::with_capacity(4); + assert!(m.insert(1, 2).is_none()); + assert!(!m.is_empty()); + assert!(m.remove(&1).is_some()); + assert!(m.is_empty()); +} + +#[test] +fn test_remove() { + let mut m = HashMap::new(); + m.insert(1, 2); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); +} + +#[test] +fn test_remove_entry() { + let mut m = HashMap::new(); + m.insert(1, 2); + assert_eq!(m.remove_entry(&1), Some((1, 2))); + assert_eq!(m.remove(&1), None); +} + +#[test] +fn test_iterate() { + let mut m = HashMap::with_capacity(4); + for i in 0..32 { + assert!(m.insert(i, i * 2).is_none()); + } + assert_eq!(m.len(), 32); + + let mut observed: u32 = 0; + + for (k, v) in &m { + assert_eq!(*v, *k * 2); + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); +} + +#[test] +fn test_keys() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let keys: Vec<_> = map.keys().cloned().collect(); + assert_eq!(keys.len(), 3); + assert!(keys.contains(&1)); + assert!(keys.contains(&2)); + assert!(keys.contains(&3)); +} + +#[test] +fn test_values() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let values: Vec<_> = map.values().cloned().collect(); + assert_eq!(values.len(), 3); + assert!(values.contains(&'a')); + assert!(values.contains(&'b')); + assert!(values.contains(&'c')); +} + +#[test] +fn test_values_mut() { + let vec = vec![(1, 1), (2, 2), (3, 3)]; + let mut map: HashMap<_, _> = vec.into_iter().collect(); + for value in map.values_mut() { + *value = (*value) * 2 + } + let values: Vec<_> = map.values().cloned().collect(); + assert_eq!(values.len(), 3); + assert!(values.contains(&2)); + assert!(values.contains(&4)); + assert!(values.contains(&6)); +} + +#[test] +fn test_into_keys() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let keys: Vec<_> = map.into_keys().collect(); + + assert_eq!(keys.len(), 3); + assert!(keys.contains(&1)); + assert!(keys.contains(&2)); + assert!(keys.contains(&3)); +} + +#[test] +fn test_into_values() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map: HashMap<_, _> = vec.into_iter().collect(); + let values: Vec<_> = map.into_values().collect(); + + assert_eq!(values.len(), 3); + assert!(values.contains(&'a')); + assert!(values.contains(&'b')); + assert!(values.contains(&'c')); +} + +#[test] +fn test_find() { + let mut m = HashMap::new(); + assert!(m.get(&1).is_none()); + m.insert(1, 2); + match m.get(&1) { + None => panic!(), + Some(v) => assert_eq!(*v, 2), + } +} + +#[test] +fn test_eq() { + let mut m1 = HashMap::new(); + m1.insert(1, 2); + m1.insert(2, 3); + m1.insert(3, 4); + + let mut m2 = HashMap::new(); + m2.insert(1, 2); + m2.insert(2, 3); + + assert!(m1 != m2); + + m2.insert(3, 4); + + assert_eq!(m1, m2); +} + +#[test] +fn test_show() { + let mut map = HashMap::new(); + let empty: HashMap<i32, i32> = HashMap::new(); + + map.insert(1, 2); + map.insert(3, 4); + + let map_str = format!("{:?}", map); + + assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "{}"); +} + +#[test] +fn test_reserve_shrink_to_fit() { + let mut m = HashMap::new(); + m.insert(0, 0); + m.remove(&0); + assert!(m.capacity() >= m.len()); + for i in 0..128 { + m.insert(i, i); + } + m.reserve(256); + + let usable_cap = m.capacity(); + for i in 128..(128 + 256) { + m.insert(i, i); + assert_eq!(m.capacity(), usable_cap); + } + + for i in 100..(128 + 256) { + assert_eq!(m.remove(&i), Some(i)); + } + m.shrink_to_fit(); + + assert_eq!(m.len(), 100); + assert!(!m.is_empty()); + assert!(m.capacity() >= m.len()); + + for i in 0..100 { + assert_eq!(m.remove(&i), Some(i)); + } + m.shrink_to_fit(); + m.insert(0, 0); + + assert_eq!(m.len(), 1); + assert!(m.capacity() >= m.len()); + assert_eq!(m.remove(&0), Some(0)); +} + +#[test] +fn test_from_iter() { + let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + for &(k, v) in &xs { + assert_eq!(map.get(&k), Some(&v)); + } + + assert_eq!(map.iter().len(), xs.len() - 1); +} + +#[test] +fn test_size_hint() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.size_hint(), (3, Some(3))); +} + +#[test] +fn test_iter_len() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); +} + +#[test] +fn test_mut_size_hint() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.size_hint(), (3, Some(3))); +} + +#[test] +fn test_iter_mut_len() { + let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); +} + +#[test] +fn test_index() { + let mut map = HashMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + assert_eq!(map[&2], 1); +} + +#[test] +#[should_panic] +fn test_index_nonexistent() { + let mut map = HashMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + map[&4]; +} + +#[test] +fn test_entry() { + let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + // Existing key (insert) + match map.entry(1) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + assert_eq!(view.get(), &10); + assert_eq!(view.insert(100), 10); + } + } + assert_eq!(map.get(&1).unwrap(), &100); + assert_eq!(map.len(), 6); + + // Existing key (update) + match map.entry(2) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + let v = view.get_mut(); + let new_v = (*v) * 10; + *v = new_v; + } + } + assert_eq!(map.get(&2).unwrap(), &200); + assert_eq!(map.len(), 6); + + // Existing key (take) + match map.entry(3) { + Vacant(_) => unreachable!(), + Occupied(view) => { + assert_eq!(view.remove(), 30); + } + } + assert_eq!(map.get(&3), None); + assert_eq!(map.len(), 5); + + // Inexistent key (insert) + match map.entry(10) { + Occupied(_) => unreachable!(), + Vacant(view) => { + assert_eq!(*view.insert(1000), 1000); + } + } + assert_eq!(map.get(&10).unwrap(), &1000); + assert_eq!(map.len(), 6); +} + +#[test] +fn test_entry_take_doesnt_corrupt() { + #![allow(deprecated)] //rand + // Test for #19292 + fn check(m: &HashMap<i32, ()>) { + for k in m.keys() { + assert!(m.contains_key(k), "{} is in keys() but not in the map?", k); + } + } + + let mut m = HashMap::new(); + let mut rng = thread_rng(); + + // Populate the map with some items. + for _ in 0..50 { + let x = rng.gen_range(-10, 10); + m.insert(x, ()); + } + + for _ in 0..1000 { + let x = rng.gen_range(-10, 10); + match m.entry(x) { + Vacant(_) => {} + Occupied(e) => { + e.remove(); + } + } + + check(&m); + } +} + +#[test] +fn test_extend_ref() { + let mut a = HashMap::new(); + a.insert(1, "one"); + let mut b = HashMap::new(); + b.insert(2, "two"); + b.insert(3, "three"); + + a.extend(&b); + + assert_eq!(a.len(), 3); + assert_eq!(a[&1], "one"); + assert_eq!(a[&2], "two"); + assert_eq!(a[&3], "three"); +} + +#[test] +fn test_capacity_not_less_than_len() { + let mut a = HashMap::new(); + let mut item = 0; + + for _ in 0..116 { + a.insert(item, 0); + item += 1; + } + + assert!(a.capacity() > a.len()); + + let free = a.capacity() - a.len(); + for _ in 0..free { + a.insert(item, 0); + item += 1; + } + + assert_eq!(a.len(), a.capacity()); + + // Insert at capacity should cause allocation. + a.insert(item, 0); + assert!(a.capacity() > a.len()); +} + +#[test] +fn test_occupied_entry_key() { + let mut a = HashMap::new(); + let key = "hello there"; + let value = "value goes here"; + assert!(a.is_empty()); + a.insert(key.clone(), value.clone()); + assert_eq!(a.len(), 1); + assert_eq!(a[key], value); + + match a.entry(key.clone()) { + Vacant(_) => panic!(), + Occupied(e) => assert_eq!(key, *e.key()), + } + assert_eq!(a.len(), 1); + assert_eq!(a[key], value); +} + +#[test] +fn test_vacant_entry_key() { + let mut a = HashMap::new(); + let key = "hello there"; + let value = "value goes here"; + + assert!(a.is_empty()); + match a.entry(key.clone()) { + Occupied(_) => panic!(), + Vacant(e) => { + assert_eq!(key, *e.key()); + e.insert(value.clone()); + } + } + assert_eq!(a.len(), 1); + assert_eq!(a[key], value); +} + +#[test] +fn test_retain() { + let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect(); + + map.retain(|&k, _| k % 2 == 0); + assert_eq!(map.len(), 50); + assert_eq!(map[&2], 20); + assert_eq!(map[&4], 40); + assert_eq!(map[&6], 60); +} + +#[test] +fn test_try_reserve() { + let mut empty_bytes: HashMap<u8, u8> = HashMap::new(); + + const MAX_USIZE: usize = usize::MAX; + + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) { + } else { + panic!("usize::MAX should trigger an overflow!"); + } + + if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) { + } else { + panic!("usize::MAX / 8 should trigger an OOM!") + } +} + +#[test] +fn test_raw_entry() { + use super::RawEntryMut::{Occupied, Vacant}; + + let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; + + let mut map: HashMap<_, _> = xs.iter().cloned().collect(); + + let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 { + use core::hash::{BuildHasher, Hash, Hasher}; + + let mut hasher = map.hasher().build_hasher(); + k.hash(&mut hasher); + hasher.finish() + }; + + // Existing key (insert) + match map.raw_entry_mut().from_key(&1) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + assert_eq!(view.get(), &10); + assert_eq!(view.insert(100), 10); + } + } + let hash1 = compute_hash(&map, 1); + assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100)); + assert_eq!(map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(), (&1, &100)); + assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(), (&1, &100)); + assert_eq!(map.len(), 6); + + // Existing key (update) + match map.raw_entry_mut().from_key(&2) { + Vacant(_) => unreachable!(), + Occupied(mut view) => { + let v = view.get_mut(); + let new_v = (*v) * 10; + *v = new_v; + } + } + let hash2 = compute_hash(&map, 2); + assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200)); + assert_eq!(map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(), (&2, &200)); + assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(), (&2, &200)); + assert_eq!(map.len(), 6); + + // Existing key (take) + let hash3 = compute_hash(&map, 3); + match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) { + Vacant(_) => unreachable!(), + Occupied(view) => { + assert_eq!(view.remove_entry(), (3, 30)); + } + } + assert_eq!(map.raw_entry().from_key(&3), None); + assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None); + assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None); + assert_eq!(map.len(), 5); + + // Nonexistent key (insert) + match map.raw_entry_mut().from_key(&10) { + Occupied(_) => unreachable!(), + Vacant(view) => { + assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000)); + } + } + assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000)); + assert_eq!(map.len(), 6); + + // Ensure all lookup methods produce equivalent results. + for k in 0..12 { + let hash = compute_hash(&map, k); + let v = map.get(&k).cloned(); + let kv = v.as_ref().map(|v| (&k, v)); + + assert_eq!(map.raw_entry().from_key(&k), kv); + assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv); + assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv); + + match map.raw_entry_mut().from_key(&k) { + Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), + Vacant(_) => assert_eq!(v, None), + } + match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) { + Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), + Vacant(_) => assert_eq!(v, None), + } + match map.raw_entry_mut().from_hash(hash, |q| *q == k) { + Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv), + Vacant(_) => assert_eq!(v, None), + } + } +} diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 10bf917daea..8c39725ef35 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::borrow::Borrow; use crate::collections::TryReserveError; use crate::fmt; @@ -1579,422 +1582,3 @@ fn assert_covariance() { d } } - -#[cfg(test)] -mod test_set { - use super::super::map::RandomState; - use super::HashSet; - - #[test] - fn test_zero_capacities() { - type HS = HashSet<i32>; - - let s = HS::new(); - assert_eq!(s.capacity(), 0); - - let s = HS::default(); - assert_eq!(s.capacity(), 0); - - let s = HS::with_hasher(RandomState::new()); - assert_eq!(s.capacity(), 0); - - let s = HS::with_capacity(0); - assert_eq!(s.capacity(), 0); - - let s = HS::with_capacity_and_hasher(0, RandomState::new()); - assert_eq!(s.capacity(), 0); - - let mut s = HS::new(); - s.insert(1); - s.insert(2); - s.remove(&1); - s.remove(&2); - s.shrink_to_fit(); - assert_eq!(s.capacity(), 0); - - let mut s = HS::new(); - s.reserve(0); - assert_eq!(s.capacity(), 0); - } - - #[test] - fn test_disjoint() { - let mut xs = HashSet::new(); - let mut ys = HashSet::new(); - assert!(xs.is_disjoint(&ys)); - assert!(ys.is_disjoint(&xs)); - assert!(xs.insert(5)); - assert!(ys.insert(11)); - assert!(xs.is_disjoint(&ys)); - assert!(ys.is_disjoint(&xs)); - assert!(xs.insert(7)); - assert!(xs.insert(19)); - assert!(xs.insert(4)); - assert!(ys.insert(2)); - assert!(ys.insert(-11)); - assert!(xs.is_disjoint(&ys)); - assert!(ys.is_disjoint(&xs)); - assert!(ys.insert(7)); - assert!(!xs.is_disjoint(&ys)); - assert!(!ys.is_disjoint(&xs)); - } - - #[test] - fn test_subset_and_superset() { - let mut a = HashSet::new(); - assert!(a.insert(0)); - assert!(a.insert(5)); - assert!(a.insert(11)); - assert!(a.insert(7)); - - let mut b = HashSet::new(); - assert!(b.insert(0)); - assert!(b.insert(7)); - assert!(b.insert(19)); - assert!(b.insert(250)); - assert!(b.insert(11)); - assert!(b.insert(200)); - - assert!(!a.is_subset(&b)); - assert!(!a.is_superset(&b)); - assert!(!b.is_subset(&a)); - assert!(!b.is_superset(&a)); - - assert!(b.insert(5)); - - assert!(a.is_subset(&b)); - assert!(!a.is_superset(&b)); - assert!(!b.is_subset(&a)); - assert!(b.is_superset(&a)); - } - - #[test] - fn test_iterate() { - let mut a = HashSet::new(); - for i in 0..32 { - assert!(a.insert(i)); - } - let mut observed: u32 = 0; - for k in &a { - observed |= 1 << *k; - } - assert_eq!(observed, 0xFFFF_FFFF); - } - - #[test] - fn test_intersection() { - let mut a = HashSet::new(); - let mut b = HashSet::new(); - assert!(a.intersection(&b).next().is_none()); - - assert!(a.insert(11)); - assert!(a.insert(1)); - assert!(a.insert(3)); - assert!(a.insert(77)); - assert!(a.insert(103)); - assert!(a.insert(5)); - assert!(a.insert(-5)); - - assert!(b.insert(2)); - assert!(b.insert(11)); - assert!(b.insert(77)); - assert!(b.insert(-9)); - assert!(b.insert(-42)); - assert!(b.insert(5)); - assert!(b.insert(3)); - - let mut i = 0; - let expected = [3, 5, 11, 77]; - for x in a.intersection(&b) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - - assert!(a.insert(9)); // make a bigger than b - - i = 0; - for x in a.intersection(&b) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - - i = 0; - for x in b.intersection(&a) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - } - - #[test] - fn test_difference() { - let mut a = HashSet::new(); - let mut b = HashSet::new(); - - assert!(a.insert(1)); - assert!(a.insert(3)); - assert!(a.insert(5)); - assert!(a.insert(9)); - assert!(a.insert(11)); - - assert!(b.insert(3)); - assert!(b.insert(9)); - - let mut i = 0; - let expected = [1, 5, 11]; - for x in a.difference(&b) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - } - - #[test] - fn test_symmetric_difference() { - let mut a = HashSet::new(); - let mut b = HashSet::new(); - - assert!(a.insert(1)); - assert!(a.insert(3)); - assert!(a.insert(5)); - assert!(a.insert(9)); - assert!(a.insert(11)); - - assert!(b.insert(-2)); - assert!(b.insert(3)); - assert!(b.insert(9)); - assert!(b.insert(14)); - assert!(b.insert(22)); - - let mut i = 0; - let expected = [-2, 1, 5, 11, 14, 22]; - for x in a.symmetric_difference(&b) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - } - - #[test] - fn test_union() { - let mut a = HashSet::new(); - let mut b = HashSet::new(); - assert!(a.union(&b).next().is_none()); - assert!(b.union(&a).next().is_none()); - - assert!(a.insert(1)); - assert!(a.insert(3)); - assert!(a.insert(11)); - assert!(a.insert(16)); - assert!(a.insert(19)); - assert!(a.insert(24)); - - assert!(b.insert(-2)); - assert!(b.insert(1)); - assert!(b.insert(5)); - assert!(b.insert(9)); - assert!(b.insert(13)); - assert!(b.insert(19)); - - let mut i = 0; - let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; - for x in a.union(&b) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - - assert!(a.insert(9)); // make a bigger than b - assert!(a.insert(5)); - - i = 0; - for x in a.union(&b) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - - i = 0; - for x in b.union(&a) { - assert!(expected.contains(x)); - i += 1 - } - assert_eq!(i, expected.len()); - } - - #[test] - fn test_from_iter() { - let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]; - - let set: HashSet<_> = xs.iter().cloned().collect(); - - for x in &xs { - assert!(set.contains(x)); - } - - assert_eq!(set.iter().len(), xs.len() - 1); - } - - #[test] - fn test_move_iter() { - let hs = { - let mut hs = HashSet::new(); - - hs.insert('a'); - hs.insert('b'); - - hs - }; - - let v = hs.into_iter().collect::<Vec<char>>(); - assert!(v == ['a', 'b'] || v == ['b', 'a']); - } - - #[test] - fn test_eq() { - // These constants once happened to expose a bug in insert(). - // I'm keeping them around to prevent a regression. - let mut s1 = HashSet::new(); - - s1.insert(1); - s1.insert(2); - s1.insert(3); - - let mut s2 = HashSet::new(); - - s2.insert(1); - s2.insert(2); - - assert!(s1 != s2); - - s2.insert(3); - - assert_eq!(s1, s2); - } - - #[test] - fn test_show() { - let mut set = HashSet::new(); - let empty = HashSet::<i32>::new(); - - set.insert(1); - set.insert(2); - - let set_str = format!("{:?}", set); - - assert!(set_str == "{1, 2}" || set_str == "{2, 1}"); - assert_eq!(format!("{:?}", empty), "{}"); - } - - #[test] - fn test_trivial_drain() { - let mut s = HashSet::<i32>::new(); - for _ in s.drain() {} - assert!(s.is_empty()); - drop(s); - - let mut s = HashSet::<i32>::new(); - drop(s.drain()); - assert!(s.is_empty()); - } - - #[test] - fn test_drain() { - let mut s: HashSet<_> = (1..100).collect(); - - // try this a bunch of times to make sure we don't screw up internal state. - for _ in 0..20 { - assert_eq!(s.len(), 99); - - { - let mut last_i = 0; - let mut d = s.drain(); - for (i, x) in d.by_ref().take(50).enumerate() { - last_i = i; - assert!(x != 0); - } - assert_eq!(last_i, 49); - } - - for _ in &s { - panic!("s should be empty!"); - } - - // reset to try again. - s.extend(1..100); - } - } - - #[test] - fn test_replace() { - use crate::hash; - - #[derive(Debug)] - struct Foo(&'static str, i32); - - impl PartialEq for Foo { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } - } - - impl Eq for Foo {} - - impl hash::Hash for Foo { - fn hash<H: hash::Hasher>(&self, h: &mut H) { - self.0.hash(h); - } - } - - let mut s = HashSet::new(); - assert_eq!(s.replace(Foo("a", 1)), None); - assert_eq!(s.len(), 1); - assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1))); - assert_eq!(s.len(), 1); - - let mut it = s.iter(); - assert_eq!(it.next(), Some(&Foo("a", 2))); - assert_eq!(it.next(), None); - } - - #[test] - fn test_extend_ref() { - let mut a = HashSet::new(); - a.insert(1); - - a.extend(&[2, 3, 4]); - - assert_eq!(a.len(), 4); - assert!(a.contains(&1)); - assert!(a.contains(&2)); - assert!(a.contains(&3)); - assert!(a.contains(&4)); - - let mut b = HashSet::new(); - b.insert(5); - b.insert(6); - - a.extend(&b); - - assert_eq!(a.len(), 6); - assert!(a.contains(&1)); - assert!(a.contains(&2)); - assert!(a.contains(&3)); - assert!(a.contains(&4)); - assert!(a.contains(&5)); - assert!(a.contains(&6)); - } - - #[test] - fn test_retain() { - let xs = [1, 2, 3, 4, 5, 6]; - let mut set: HashSet<i32> = xs.iter().cloned().collect(); - set.retain(|&k| k % 2 == 0); - assert_eq!(set.len(), 3); - assert!(set.contains(&2)); - assert!(set.contains(&4)); - assert!(set.contains(&6)); - } -} diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs new file mode 100644 index 00000000000..3582390cee4 --- /dev/null +++ b/library/std/src/collections/hash/set/tests.rs @@ -0,0 +1,415 @@ +use super::super::map::RandomState; +use super::HashSet; + +#[test] +fn test_zero_capacities() { + type HS = HashSet<i32>; + + let s = HS::new(); + assert_eq!(s.capacity(), 0); + + let s = HS::default(); + assert_eq!(s.capacity(), 0); + + let s = HS::with_hasher(RandomState::new()); + assert_eq!(s.capacity(), 0); + + let s = HS::with_capacity(0); + assert_eq!(s.capacity(), 0); + + let s = HS::with_capacity_and_hasher(0, RandomState::new()); + assert_eq!(s.capacity(), 0); + + let mut s = HS::new(); + s.insert(1); + s.insert(2); + s.remove(&1); + s.remove(&2); + s.shrink_to_fit(); + assert_eq!(s.capacity(), 0); + + let mut s = HS::new(); + s.reserve(0); + assert_eq!(s.capacity(), 0); +} + +#[test] +fn test_disjoint() { + let mut xs = HashSet::new(); + let mut ys = HashSet::new(); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(5)); + assert!(ys.insert(11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(7)); + assert!(xs.insert(19)); + assert!(xs.insert(4)); + assert!(ys.insert(2)); + assert!(ys.insert(-11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(ys.insert(7)); + assert!(!xs.is_disjoint(&ys)); + assert!(!ys.is_disjoint(&xs)); +} + +#[test] +fn test_subset_and_superset() { + let mut a = HashSet::new(); + assert!(a.insert(0)); + assert!(a.insert(5)); + assert!(a.insert(11)); + assert!(a.insert(7)); + + let mut b = HashSet::new(); + assert!(b.insert(0)); + assert!(b.insert(7)); + assert!(b.insert(19)); + assert!(b.insert(250)); + assert!(b.insert(11)); + assert!(b.insert(200)); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(!b.is_superset(&a)); + + assert!(b.insert(5)); + + assert!(a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(b.is_superset(&a)); +} + +#[test] +fn test_iterate() { + let mut a = HashSet::new(); + for i in 0..32 { + assert!(a.insert(i)); + } + let mut observed: u32 = 0; + for k in &a { + observed |= 1 << *k; + } + assert_eq!(observed, 0xFFFF_FFFF); +} + +#[test] +fn test_intersection() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + assert!(a.intersection(&b).next().is_none()); + + assert!(a.insert(11)); + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(77)); + assert!(a.insert(103)); + assert!(a.insert(5)); + assert!(a.insert(-5)); + + assert!(b.insert(2)); + assert!(b.insert(11)); + assert!(b.insert(77)); + assert!(b.insert(-9)); + assert!(b.insert(-42)); + assert!(b.insert(5)); + assert!(b.insert(3)); + + let mut i = 0; + let expected = [3, 5, 11, 77]; + for x in a.intersection(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + + assert!(a.insert(9)); // make a bigger than b + + i = 0; + for x in a.intersection(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + + i = 0; + for x in b.intersection(&a) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_difference() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(3)); + assert!(b.insert(9)); + + let mut i = 0; + let expected = [1, 5, 11]; + for x in a.difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_symmetric_difference() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(5)); + assert!(a.insert(9)); + assert!(a.insert(11)); + + assert!(b.insert(-2)); + assert!(b.insert(3)); + assert!(b.insert(9)); + assert!(b.insert(14)); + assert!(b.insert(22)); + + let mut i = 0; + let expected = [-2, 1, 5, 11, 14, 22]; + for x in a.symmetric_difference(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_union() { + let mut a = HashSet::new(); + let mut b = HashSet::new(); + assert!(a.union(&b).next().is_none()); + assert!(b.union(&a).next().is_none()); + + assert!(a.insert(1)); + assert!(a.insert(3)); + assert!(a.insert(11)); + assert!(a.insert(16)); + assert!(a.insert(19)); + assert!(a.insert(24)); + + assert!(b.insert(-2)); + assert!(b.insert(1)); + assert!(b.insert(5)); + assert!(b.insert(9)); + assert!(b.insert(13)); + assert!(b.insert(19)); + + let mut i = 0; + let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; + for x in a.union(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + + assert!(a.insert(9)); // make a bigger than b + assert!(a.insert(5)); + + i = 0; + for x in a.union(&b) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); + + i = 0; + for x in b.union(&a) { + assert!(expected.contains(x)); + i += 1 + } + assert_eq!(i, expected.len()); +} + +#[test] +fn test_from_iter() { + let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9]; + + let set: HashSet<_> = xs.iter().cloned().collect(); + + for x in &xs { + assert!(set.contains(x)); + } + + assert_eq!(set.iter().len(), xs.len() - 1); +} + +#[test] +fn test_move_iter() { + let hs = { + let mut hs = HashSet::new(); + + hs.insert('a'); + hs.insert('b'); + + hs + }; + + let v = hs.into_iter().collect::<Vec<char>>(); + assert!(v == ['a', 'b'] || v == ['b', 'a']); +} + +#[test] +fn test_eq() { + // These constants once happened to expose a bug in insert(). + // I'm keeping them around to prevent a regression. + let mut s1 = HashSet::new(); + + s1.insert(1); + s1.insert(2); + s1.insert(3); + + let mut s2 = HashSet::new(); + + s2.insert(1); + s2.insert(2); + + assert!(s1 != s2); + + s2.insert(3); + + assert_eq!(s1, s2); +} + +#[test] +fn test_show() { + let mut set = HashSet::new(); + let empty = HashSet::<i32>::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{:?}", set); + + assert!(set_str == "{1, 2}" || set_str == "{2, 1}"); + assert_eq!(format!("{:?}", empty), "{}"); +} + +#[test] +fn test_trivial_drain() { + let mut s = HashSet::<i32>::new(); + for _ in s.drain() {} + assert!(s.is_empty()); + drop(s); + + let mut s = HashSet::<i32>::new(); + drop(s.drain()); + assert!(s.is_empty()); +} + +#[test] +fn test_drain() { + let mut s: HashSet<_> = (1..100).collect(); + + // try this a bunch of times to make sure we don't screw up internal state. + for _ in 0..20 { + assert_eq!(s.len(), 99); + + { + let mut last_i = 0; + let mut d = s.drain(); + for (i, x) in d.by_ref().take(50).enumerate() { + last_i = i; + assert!(x != 0); + } + assert_eq!(last_i, 49); + } + + for _ in &s { + panic!("s should be empty!"); + } + + // reset to try again. + s.extend(1..100); + } +} + +#[test] +fn test_replace() { + use crate::hash; + + #[derive(Debug)] + struct Foo(&'static str, i32); + + impl PartialEq for Foo { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + impl Eq for Foo {} + + impl hash::Hash for Foo { + fn hash<H: hash::Hasher>(&self, h: &mut H) { + self.0.hash(h); + } + } + + let mut s = HashSet::new(); + assert_eq!(s.replace(Foo("a", 1)), None); + assert_eq!(s.len(), 1); + assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1))); + assert_eq!(s.len(), 1); + + let mut it = s.iter(); + assert_eq!(it.next(), Some(&Foo("a", 2))); + assert_eq!(it.next(), None); +} + +#[test] +fn test_extend_ref() { + let mut a = HashSet::new(); + a.insert(1); + + a.extend(&[2, 3, 4]); + + assert_eq!(a.len(), 4); + assert!(a.contains(&1)); + assert!(a.contains(&2)); + assert!(a.contains(&3)); + assert!(a.contains(&4)); + + let mut b = HashSet::new(); + b.insert(5); + b.insert(6); + + a.extend(&b); + + assert_eq!(a.len(), 6); + assert!(a.contains(&1)); + assert!(a.contains(&2)); + assert!(a.contains(&3)); + assert!(a.contains(&4)); + assert!(a.contains(&5)); + assert!(a.contains(&6)); +} + +#[test] +fn test_retain() { + let xs = [1, 2, 3, 4, 5, 6]; + let mut set: HashSet<i32> = xs.iter().cloned().collect(); + set.retain(|&k| k % 2 == 0); + assert_eq!(set.len(), 3); + assert!(set.contains(&2)); + assert!(set.contains(&4)); + assert!(set.contains(&6)); +} diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 387c588f4a0..970dea6b299 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -10,6 +10,9 @@ #![stable(feature = "env", since = "1.0.0")] +#[cfg(test)] +mod tests; + use crate::error::Error; use crate::ffi::{OsStr, OsString}; use crate::fmt; @@ -65,10 +68,9 @@ pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { /// An iterator over a snapshot of the environment variables of this process. /// -/// This structure is created by the [`std::env::vars`] function. See its -/// documentation for more. +/// This structure is created by [`env::vars()`]. See its documentation for more. /// -/// [`std::env::vars`]: vars +/// [`env::vars()`]: vars #[stable(feature = "env", since = "1.0.0")] pub struct Vars { inner: VarsOs, @@ -76,10 +78,9 @@ pub struct Vars { /// An iterator over a snapshot of the environment variables of this process. /// -/// This structure is created by the [`std::env::vars_os`] function. See -/// its documentation for more. +/// This structure is created by [`env::vars_os()`]. See its documentation for more. /// -/// [`std::env::vars_os`]: vars_os +/// [`env::vars_os()`]: vars_os #[stable(feature = "env", since = "1.0.0")] pub struct VarsOs { inner: os_imp::Env, @@ -95,10 +96,8 @@ pub struct VarsOs { /// # Panics /// /// While iterating, the returned iterator will panic if any key or value in the -/// environment is not valid unicode. If this is not desired, consider using the -/// [`env::vars_os`] function. -/// -/// [`env::vars_os`]: vars_os +/// environment is not valid unicode. If this is not desired, consider using +/// [`env::vars_os()`]. /// /// # Examples /// @@ -111,6 +110,8 @@ pub struct VarsOs { /// println!("{}: {}", key, value); /// } /// ``` +/// +/// [`env::vars_os()`]: vars_os #[stable(feature = "env", since = "1.0.0")] pub fn vars() -> Vars { Vars { inner: vars_os() } @@ -242,9 +243,9 @@ fn _var_os(key: &OsStr) -> Option<OsString> { } /// The error type for operations interacting with environment variables. -/// Possibly returned from the [`env::var`] function. +/// Possibly returned from [`env::var()`]. /// -/// [`env::var`]: var +/// [`env::var()`]: var #[derive(Debug, PartialEq, Eq, Clone)] #[stable(feature = "env", since = "1.0.0")] pub enum VarError { @@ -369,10 +370,10 @@ fn _remove_var(k: &OsStr) { /// /// The iterator element type is [`PathBuf`]. /// -/// This structure is created by the [`std::env::split_paths`] function. See its +/// This structure is created by [`env::split_paths()`]. See its /// documentation for more. /// -/// [`std::env::split_paths`]: split_paths +/// [`env::split_paths()`]: split_paths #[stable(feature = "env", since = "1.0.0")] pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a>, @@ -423,9 +424,9 @@ impl fmt::Debug for SplitPaths<'_> { } /// The error type for operations on the `PATH` variable. Possibly returned from -/// the [`env::join_paths`] function. +/// [`env::join_paths()`]. /// -/// [`env::join_paths`]: join_paths +/// [`env::join_paths()`]: join_paths #[derive(Debug)] #[stable(feature = "env", since = "1.0.0")] pub struct JoinPathsError { @@ -460,7 +461,8 @@ pub struct JoinPathsError { /// } /// ``` /// -/// Joining a path containing a colon on a Unix-like platform results in an error: +/// Joining a path containing a colon on a Unix-like platform results in an +/// error: /// /// ``` /// # if cfg!(unix) { @@ -472,8 +474,8 @@ pub struct JoinPathsError { /// # } /// ``` /// -/// Using `env::join_paths` with [`env::split_paths`] to append an item to the `PATH` environment -/// variable: +/// Using `env::join_paths()` with [`env::split_paths()`] to append an item to +/// the `PATH` environment variable: /// /// ``` /// use std::env; @@ -491,7 +493,7 @@ pub struct JoinPathsError { /// } /// ``` /// -/// [`env::split_paths`]: split_paths +/// [`env::split_paths()`]: split_paths #[stable(feature = "env", since = "1.0.0")] pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError> where @@ -664,14 +666,14 @@ pub fn current_exe() -> io::Result<PathBuf> { /// An iterator over the arguments of a process, yielding a [`String`] value for /// each argument. /// -/// This struct is created by the [`std::env::args`] function. See its -/// documentation for more. +/// This struct is created by [`env::args()`]. See its documentation +/// for more. /// /// The first element is traditionally the path of the executable, but it can be /// set to arbitrary text, and may not even exist. This means this property /// should not be relied upon for security purposes. /// -/// [`std::env::args`]: args +/// [`env::args()`]: args #[stable(feature = "env", since = "1.0.0")] pub struct Args { inner: ArgsOs, @@ -680,14 +682,14 @@ pub struct Args { /// An iterator over the arguments of a process, yielding an [`OsString`] value /// for each argument. /// -/// This struct is created by the [`std::env::args_os`] function. See its -/// documentation for more. +/// This struct is created by [`env::args_os()`]. See its documentation +/// for more. /// /// The first element is traditionally the path of the executable, but it can be /// set to arbitrary text, and may not even exist. This means this property /// should not be relied upon for security purposes. /// -/// [`std::env::args_os`]: args_os +/// [`env::args_os()`]: args_os #[stable(feature = "env", since = "1.0.0")] pub struct ArgsOs { inner: sys::args::Args, @@ -944,112 +946,3 @@ pub mod consts { #[stable(feature = "env", since = "1.0.0")] pub const EXE_EXTENSION: &str = os::EXE_EXTENSION; } - -#[cfg(test)] -mod tests { - use super::*; - - use crate::path::Path; - - #[test] - #[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)] - fn test_self_exe_path() { - let path = current_exe(); - assert!(path.is_ok()); - let path = path.unwrap(); - - // Hard to test this function - assert!(path.is_absolute()); - } - - #[test] - fn test() { - assert!((!Path::new("test-path").is_absolute())); - - #[cfg(not(target_env = "sgx"))] - current_dir().unwrap(); - } - - #[test] - #[cfg(windows)] - fn split_paths_windows() { - use crate::path::PathBuf; - - fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { - split_paths(unparsed).collect::<Vec<_>>() - == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>() - } - - assert!(check_parse("", &mut [""])); - assert!(check_parse(r#""""#, &mut [""])); - assert!(check_parse(";;", &mut ["", "", ""])); - assert!(check_parse(r"c:\", &mut [r"c:\"])); - assert!(check_parse(r"c:\;", &mut [r"c:\", ""])); - assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"])); - assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"])); - assert!(check_parse( - r#"c:\;c:\"foo;bar"\;c:\baz"#, - &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"] - )); - } - - #[test] - #[cfg(unix)] - fn split_paths_unix() { - use crate::path::PathBuf; - - fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { - split_paths(unparsed).collect::<Vec<_>>() - == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>() - } - - assert!(check_parse("", &mut [""])); - assert!(check_parse("::", &mut ["", "", ""])); - assert!(check_parse("/", &mut ["/"])); - assert!(check_parse("/:", &mut ["/", ""])); - assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"])); - } - - #[test] - #[cfg(unix)] - fn join_paths_unix() { - use crate::ffi::OsStr; - - fn test_eq(input: &[&str], output: &str) -> bool { - &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output) - } - - assert!(test_eq(&[], "")); - assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin")); - assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:")); - assert!(join_paths(["/te:st"].iter().cloned()).is_err()); - } - - #[test] - #[cfg(windows)] - fn join_paths_windows() { - use crate::ffi::OsStr; - - fn test_eq(input: &[&str], output: &str) -> bool { - &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output) - } - - assert!(test_eq(&[], "")); - assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\")); - assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;")); - assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#)); - assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err()); - } - - #[test] - fn args_debug() { - assert_eq!( - format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()), - format!("{:?}", args()) - ); - assert_eq!( - format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()), - format!("{:?}", args_os()) - ); - } -} diff --git a/library/std/src/env/tests.rs b/library/std/src/env/tests.rs new file mode 100644 index 00000000000..94cace03af6 --- /dev/null +++ b/library/std/src/env/tests.rs @@ -0,0 +1,102 @@ +use super::*; + +use crate::path::Path; + +#[test] +#[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)] +fn test_self_exe_path() { + let path = current_exe(); + assert!(path.is_ok()); + let path = path.unwrap(); + + // Hard to test this function + assert!(path.is_absolute()); +} + +#[test] +fn test() { + assert!((!Path::new("test-path").is_absolute())); + + #[cfg(not(target_env = "sgx"))] + current_dir().unwrap(); +} + +#[test] +#[cfg(windows)] +fn split_paths_windows() { + use crate::path::PathBuf; + + fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { + split_paths(unparsed).collect::<Vec<_>>() + == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>() + } + + assert!(check_parse("", &mut [""])); + assert!(check_parse(r#""""#, &mut [""])); + assert!(check_parse(";;", &mut ["", "", ""])); + assert!(check_parse(r"c:\", &mut [r"c:\"])); + assert!(check_parse(r"c:\;", &mut [r"c:\", ""])); + assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"])); + assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"])); + assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#, &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"])); +} + +#[test] +#[cfg(unix)] +fn split_paths_unix() { + use crate::path::PathBuf; + + fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { + split_paths(unparsed).collect::<Vec<_>>() + == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>() + } + + assert!(check_parse("", &mut [""])); + assert!(check_parse("::", &mut ["", "", ""])); + assert!(check_parse("/", &mut ["/"])); + assert!(check_parse("/:", &mut ["/", ""])); + assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"])); +} + +#[test] +#[cfg(unix)] +fn join_paths_unix() { + use crate::ffi::OsStr; + + fn test_eq(input: &[&str], output: &str) -> bool { + &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output) + } + + assert!(test_eq(&[], "")); + assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin")); + assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:")); + assert!(join_paths(["/te:st"].iter().cloned()).is_err()); +} + +#[test] +#[cfg(windows)] +fn join_paths_windows() { + use crate::ffi::OsStr; + + fn test_eq(input: &[&str], output: &str) -> bool { + &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output) + } + + assert!(test_eq(&[], "")); + assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\")); + assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;")); + assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#)); + assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err()); +} + +#[test] +fn args_debug() { + assert_eq!( + format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()), + format!("{:?}", args()) + ); + assert_eq!( + format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()), + format!("{:?}", args_os()) + ); +} diff --git a/library/std/src/error.rs b/library/std/src/error.rs index d3b0f8ceb68..8da03343976 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -13,6 +13,9 @@ // coherence challenge (e.g., specialization, neg impls, etc) we can // reconsider what crate these items belong in. +#[cfg(test)] +mod tests; + use core::array; use core::convert::Infallible; @@ -738,44 +741,3 @@ impl dyn Error + Send + Sync { }) } } - -#[cfg(test)] -mod tests { - use super::Error; - use crate::fmt; - - #[derive(Debug, PartialEq)] - struct A; - #[derive(Debug, PartialEq)] - struct B; - - impl fmt::Display for A { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "A") - } - } - impl fmt::Display for B { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "B") - } - } - - impl Error for A {} - impl Error for B {} - - #[test] - fn downcasting() { - let mut a = A; - let a = &mut a as &mut (dyn Error + 'static); - assert_eq!(a.downcast_ref::<A>(), Some(&A)); - assert_eq!(a.downcast_ref::<B>(), None); - assert_eq!(a.downcast_mut::<A>(), Some(&mut A)); - assert_eq!(a.downcast_mut::<B>(), None); - - let a: Box<dyn Error> = Box::new(A); - match a.downcast::<B>() { - Ok(..) => panic!("expected error"), - Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A), - } - } -} diff --git a/library/std/src/error/tests.rs b/library/std/src/error/tests.rs new file mode 100644 index 00000000000..66d6924f34d --- /dev/null +++ b/library/std/src/error/tests.rs @@ -0,0 +1,37 @@ +use super::Error; +use crate::fmt; + +#[derive(Debug, PartialEq)] +struct A; +#[derive(Debug, PartialEq)] +struct B; + +impl fmt::Display for A { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "A") + } +} +impl fmt::Display for B { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "B") + } +} + +impl Error for A {} +impl Error for B {} + +#[test] +fn downcasting() { + let mut a = A; + let a = &mut a as &mut (dyn Error + 'static); + assert_eq!(a.downcast_ref::<A>(), Some(&A)); + assert_eq!(a.downcast_ref::<B>(), None); + assert_eq!(a.downcast_mut::<A>(), Some(&mut A)); + assert_eq!(a.downcast_mut::<B>(), None); + + let a: Box<dyn Error> = Box::new(A); + match a.downcast::<B>() { + Ok(..) => panic!("expected error"), + Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A), + } +} diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index c905bcf5e3d..59c2da5273b 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -11,6 +11,9 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] +#[cfg(test)] +mod tests; + #[cfg(not(test))] use crate::intrinsics; #[cfg(not(test))] @@ -909,766 +912,3 @@ impl f32 { x } } - -#[cfg(test)] -mod tests { - use crate::f32::consts; - use crate::num::FpCategory as Fp; - use crate::num::*; - - #[test] - fn test_num_f32() { - test_num(10f32, 2f32); - } - - #[test] - fn test_min_nan() { - assert_eq!(f32::NAN.min(2.0), 2.0); - assert_eq!(2.0f32.min(f32::NAN), 2.0); - } - - #[test] - fn test_max_nan() { - assert_eq!(f32::NAN.max(2.0), 2.0); - assert_eq!(2.0f32.max(f32::NAN), 2.0); - } - - #[test] - fn test_nan() { - let nan: f32 = f32::NAN; - assert!(nan.is_nan()); - assert!(!nan.is_infinite()); - assert!(!nan.is_finite()); - assert!(!nan.is_normal()); - assert!(nan.is_sign_positive()); - assert!(!nan.is_sign_negative()); - assert_eq!(Fp::Nan, nan.classify()); - } - - #[test] - fn test_infinity() { - let inf: f32 = f32::INFINITY; - assert!(inf.is_infinite()); - assert!(!inf.is_finite()); - assert!(inf.is_sign_positive()); - assert!(!inf.is_sign_negative()); - assert!(!inf.is_nan()); - assert!(!inf.is_normal()); - assert_eq!(Fp::Infinite, inf.classify()); - } - - #[test] - fn test_neg_infinity() { - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(neg_inf.is_infinite()); - assert!(!neg_inf.is_finite()); - assert!(!neg_inf.is_sign_positive()); - assert!(neg_inf.is_sign_negative()); - assert!(!neg_inf.is_nan()); - assert!(!neg_inf.is_normal()); - assert_eq!(Fp::Infinite, neg_inf.classify()); - } - - #[test] - fn test_zero() { - let zero: f32 = 0.0f32; - assert_eq!(0.0, zero); - assert!(!zero.is_infinite()); - assert!(zero.is_finite()); - assert!(zero.is_sign_positive()); - assert!(!zero.is_sign_negative()); - assert!(!zero.is_nan()); - assert!(!zero.is_normal()); - assert_eq!(Fp::Zero, zero.classify()); - } - - #[test] - fn test_neg_zero() { - let neg_zero: f32 = -0.0; - assert_eq!(0.0, neg_zero); - assert!(!neg_zero.is_infinite()); - assert!(neg_zero.is_finite()); - assert!(!neg_zero.is_sign_positive()); - assert!(neg_zero.is_sign_negative()); - assert!(!neg_zero.is_nan()); - assert!(!neg_zero.is_normal()); - assert_eq!(Fp::Zero, neg_zero.classify()); - } - - #[test] - fn test_one() { - let one: f32 = 1.0f32; - assert_eq!(1.0, one); - assert!(!one.is_infinite()); - assert!(one.is_finite()); - assert!(one.is_sign_positive()); - assert!(!one.is_sign_negative()); - assert!(!one.is_nan()); - assert!(one.is_normal()); - assert_eq!(Fp::Normal, one.classify()); - } - - #[test] - fn test_is_nan() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(nan.is_nan()); - assert!(!0.0f32.is_nan()); - assert!(!5.3f32.is_nan()); - assert!(!(-10.732f32).is_nan()); - assert!(!inf.is_nan()); - assert!(!neg_inf.is_nan()); - } - - #[test] - fn test_is_infinite() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(!nan.is_infinite()); - assert!(inf.is_infinite()); - assert!(neg_inf.is_infinite()); - assert!(!0.0f32.is_infinite()); - assert!(!42.8f32.is_infinite()); - assert!(!(-109.2f32).is_infinite()); - } - - #[test] - fn test_is_finite() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert!(!nan.is_finite()); - assert!(!inf.is_finite()); - assert!(!neg_inf.is_finite()); - assert!(0.0f32.is_finite()); - assert!(42.8f32.is_finite()); - assert!((-109.2f32).is_finite()); - } - - #[test] - fn test_is_normal() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let zero: f32 = 0.0f32; - let neg_zero: f32 = -0.0; - assert!(!nan.is_normal()); - assert!(!inf.is_normal()); - assert!(!neg_inf.is_normal()); - assert!(!zero.is_normal()); - assert!(!neg_zero.is_normal()); - assert!(1f32.is_normal()); - assert!(1e-37f32.is_normal()); - assert!(!1e-38f32.is_normal()); - } - - #[test] - fn test_classify() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let zero: f32 = 0.0f32; - let neg_zero: f32 = -0.0; - assert_eq!(nan.classify(), Fp::Nan); - assert_eq!(inf.classify(), Fp::Infinite); - assert_eq!(neg_inf.classify(), Fp::Infinite); - assert_eq!(zero.classify(), Fp::Zero); - assert_eq!(neg_zero.classify(), Fp::Zero); - assert_eq!(1f32.classify(), Fp::Normal); - assert_eq!(1e-37f32.classify(), Fp::Normal); - assert_eq!(1e-38f32.classify(), Fp::Subnormal); - } - - #[test] - fn test_floor() { - assert_approx_eq!(1.0f32.floor(), 1.0f32); - assert_approx_eq!(1.3f32.floor(), 1.0f32); - assert_approx_eq!(1.5f32.floor(), 1.0f32); - assert_approx_eq!(1.7f32.floor(), 1.0f32); - assert_approx_eq!(0.0f32.floor(), 0.0f32); - assert_approx_eq!((-0.0f32).floor(), -0.0f32); - assert_approx_eq!((-1.0f32).floor(), -1.0f32); - assert_approx_eq!((-1.3f32).floor(), -2.0f32); - assert_approx_eq!((-1.5f32).floor(), -2.0f32); - assert_approx_eq!((-1.7f32).floor(), -2.0f32); - } - - #[test] - fn test_ceil() { - assert_approx_eq!(1.0f32.ceil(), 1.0f32); - assert_approx_eq!(1.3f32.ceil(), 2.0f32); - assert_approx_eq!(1.5f32.ceil(), 2.0f32); - assert_approx_eq!(1.7f32.ceil(), 2.0f32); - assert_approx_eq!(0.0f32.ceil(), 0.0f32); - assert_approx_eq!((-0.0f32).ceil(), -0.0f32); - assert_approx_eq!((-1.0f32).ceil(), -1.0f32); - assert_approx_eq!((-1.3f32).ceil(), -1.0f32); - assert_approx_eq!((-1.5f32).ceil(), -1.0f32); - assert_approx_eq!((-1.7f32).ceil(), -1.0f32); - } - - #[test] - fn test_round() { - assert_approx_eq!(1.0f32.round(), 1.0f32); - assert_approx_eq!(1.3f32.round(), 1.0f32); - assert_approx_eq!(1.5f32.round(), 2.0f32); - assert_approx_eq!(1.7f32.round(), 2.0f32); - assert_approx_eq!(0.0f32.round(), 0.0f32); - assert_approx_eq!((-0.0f32).round(), -0.0f32); - assert_approx_eq!((-1.0f32).round(), -1.0f32); - assert_approx_eq!((-1.3f32).round(), -1.0f32); - assert_approx_eq!((-1.5f32).round(), -2.0f32); - assert_approx_eq!((-1.7f32).round(), -2.0f32); - } - - #[test] - fn test_trunc() { - assert_approx_eq!(1.0f32.trunc(), 1.0f32); - assert_approx_eq!(1.3f32.trunc(), 1.0f32); - assert_approx_eq!(1.5f32.trunc(), 1.0f32); - assert_approx_eq!(1.7f32.trunc(), 1.0f32); - assert_approx_eq!(0.0f32.trunc(), 0.0f32); - assert_approx_eq!((-0.0f32).trunc(), -0.0f32); - assert_approx_eq!((-1.0f32).trunc(), -1.0f32); - assert_approx_eq!((-1.3f32).trunc(), -1.0f32); - assert_approx_eq!((-1.5f32).trunc(), -1.0f32); - assert_approx_eq!((-1.7f32).trunc(), -1.0f32); - } - - #[test] - fn test_fract() { - assert_approx_eq!(1.0f32.fract(), 0.0f32); - assert_approx_eq!(1.3f32.fract(), 0.3f32); - assert_approx_eq!(1.5f32.fract(), 0.5f32); - assert_approx_eq!(1.7f32.fract(), 0.7f32); - assert_approx_eq!(0.0f32.fract(), 0.0f32); - assert_approx_eq!((-0.0f32).fract(), -0.0f32); - assert_approx_eq!((-1.0f32).fract(), -0.0f32); - assert_approx_eq!((-1.3f32).fract(), -0.3f32); - assert_approx_eq!((-1.5f32).fract(), -0.5f32); - assert_approx_eq!((-1.7f32).fract(), -0.7f32); - } - - #[test] - fn test_abs() { - assert_eq!(f32::INFINITY.abs(), f32::INFINITY); - assert_eq!(1f32.abs(), 1f32); - assert_eq!(0f32.abs(), 0f32); - assert_eq!((-0f32).abs(), 0f32); - assert_eq!((-1f32).abs(), 1f32); - assert_eq!(f32::NEG_INFINITY.abs(), f32::INFINITY); - assert_eq!((1f32 / f32::NEG_INFINITY).abs(), 0f32); - assert!(f32::NAN.abs().is_nan()); - } - - #[test] - fn test_signum() { - assert_eq!(f32::INFINITY.signum(), 1f32); - assert_eq!(1f32.signum(), 1f32); - assert_eq!(0f32.signum(), 1f32); - assert_eq!((-0f32).signum(), -1f32); - assert_eq!((-1f32).signum(), -1f32); - assert_eq!(f32::NEG_INFINITY.signum(), -1f32); - assert_eq!((1f32 / f32::NEG_INFINITY).signum(), -1f32); - assert!(f32::NAN.signum().is_nan()); - } - - #[test] - fn test_is_sign_positive() { - assert!(f32::INFINITY.is_sign_positive()); - assert!(1f32.is_sign_positive()); - assert!(0f32.is_sign_positive()); - assert!(!(-0f32).is_sign_positive()); - assert!(!(-1f32).is_sign_positive()); - assert!(!f32::NEG_INFINITY.is_sign_positive()); - assert!(!(1f32 / f32::NEG_INFINITY).is_sign_positive()); - assert!(f32::NAN.is_sign_positive()); - assert!(!(-f32::NAN).is_sign_positive()); - } - - #[test] - fn test_is_sign_negative() { - assert!(!f32::INFINITY.is_sign_negative()); - assert!(!1f32.is_sign_negative()); - assert!(!0f32.is_sign_negative()); - assert!((-0f32).is_sign_negative()); - assert!((-1f32).is_sign_negative()); - assert!(f32::NEG_INFINITY.is_sign_negative()); - assert!((1f32 / f32::NEG_INFINITY).is_sign_negative()); - assert!(!f32::NAN.is_sign_negative()); - assert!((-f32::NAN).is_sign_negative()); - } - - #[test] - fn test_mul_add() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05); - assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65); - assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2); - assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6); - assert!(nan.mul_add(7.8, 9.0).is_nan()); - assert_eq!(inf.mul_add(7.8, 9.0), inf); - assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf); - assert_eq!(8.9f32.mul_add(inf, 3.2), inf); - assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf); - } - - #[test] - fn test_recip() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(1.0f32.recip(), 1.0); - assert_eq!(2.0f32.recip(), 0.5); - assert_eq!((-0.4f32).recip(), -2.5); - assert_eq!(0.0f32.recip(), inf); - assert!(nan.recip().is_nan()); - assert_eq!(inf.recip(), 0.0); - assert_eq!(neg_inf.recip(), 0.0); - } - - #[test] - fn test_powi() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(1.0f32.powi(1), 1.0); - assert_approx_eq!((-3.1f32).powi(2), 9.61); - assert_approx_eq!(5.9f32.powi(-2), 0.028727); - assert_eq!(8.3f32.powi(0), 1.0); - assert!(nan.powi(2).is_nan()); - assert_eq!(inf.powi(3), inf); - assert_eq!(neg_inf.powi(2), inf); - } - - #[test] - fn test_powf() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(1.0f32.powf(1.0), 1.0); - assert_approx_eq!(3.4f32.powf(4.5), 246.408218); - assert_approx_eq!(2.7f32.powf(-3.2), 0.041652); - assert_approx_eq!((-3.1f32).powf(2.0), 9.61); - assert_approx_eq!(5.9f32.powf(-2.0), 0.028727); - assert_eq!(8.3f32.powf(0.0), 1.0); - assert!(nan.powf(2.0).is_nan()); - assert_eq!(inf.powf(2.0), inf); - assert_eq!(neg_inf.powf(3.0), neg_inf); - } - - #[test] - fn test_sqrt_domain() { - assert!(f32::NAN.sqrt().is_nan()); - assert!(f32::NEG_INFINITY.sqrt().is_nan()); - assert!((-1.0f32).sqrt().is_nan()); - assert_eq!((-0.0f32).sqrt(), -0.0); - assert_eq!(0.0f32.sqrt(), 0.0); - assert_eq!(1.0f32.sqrt(), 1.0); - assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY); - } - - #[test] - fn test_exp() { - assert_eq!(1.0, 0.0f32.exp()); - assert_approx_eq!(2.718282, 1.0f32.exp()); - assert_approx_eq!(148.413162, 5.0f32.exp()); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf, inf.exp()); - assert_eq!(0.0, neg_inf.exp()); - assert!(nan.exp().is_nan()); - } - - #[test] - fn test_exp2() { - assert_eq!(32.0, 5.0f32.exp2()); - assert_eq!(1.0, 0.0f32.exp2()); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf, inf.exp2()); - assert_eq!(0.0, neg_inf.exp2()); - assert!(nan.exp2().is_nan()); - } - - #[test] - fn test_ln() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(1.0f32.exp().ln(), 1.0); - assert!(nan.ln().is_nan()); - assert_eq!(inf.ln(), inf); - assert!(neg_inf.ln().is_nan()); - assert!((-2.3f32).ln().is_nan()); - assert_eq!((-0.0f32).ln(), neg_inf); - assert_eq!(0.0f32.ln(), neg_inf); - assert_approx_eq!(4.0f32.ln(), 1.386294); - } - - #[test] - fn test_log() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(10.0f32.log(10.0), 1.0); - assert_approx_eq!(2.3f32.log(3.5), 0.664858); - assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0); - assert!(1.0f32.log(1.0).is_nan()); - assert!(1.0f32.log(-13.9).is_nan()); - assert!(nan.log(2.3).is_nan()); - assert_eq!(inf.log(10.0), inf); - assert!(neg_inf.log(8.8).is_nan()); - assert!((-2.3f32).log(0.1).is_nan()); - assert_eq!((-0.0f32).log(2.0), neg_inf); - assert_eq!(0.0f32.log(7.0), neg_inf); - } - - #[test] - fn test_log2() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(10.0f32.log2(), 3.321928); - assert_approx_eq!(2.3f32.log2(), 1.201634); - assert_approx_eq!(1.0f32.exp().log2(), 1.442695); - assert!(nan.log2().is_nan()); - assert_eq!(inf.log2(), inf); - assert!(neg_inf.log2().is_nan()); - assert!((-2.3f32).log2().is_nan()); - assert_eq!((-0.0f32).log2(), neg_inf); - assert_eq!(0.0f32.log2(), neg_inf); - } - - #[test] - fn test_log10() { - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(10.0f32.log10(), 1.0); - assert_approx_eq!(2.3f32.log10(), 0.361728); - assert_approx_eq!(1.0f32.exp().log10(), 0.434294); - assert_eq!(1.0f32.log10(), 0.0); - assert!(nan.log10().is_nan()); - assert_eq!(inf.log10(), inf); - assert!(neg_inf.log10().is_nan()); - assert!((-2.3f32).log10().is_nan()); - assert_eq!((-0.0f32).log10(), neg_inf); - assert_eq!(0.0f32.log10(), neg_inf); - } - - #[test] - fn test_to_degrees() { - let pi: f32 = consts::PI; - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(0.0f32.to_degrees(), 0.0); - assert_approx_eq!((-5.8f32).to_degrees(), -332.315521); - assert_eq!(pi.to_degrees(), 180.0); - assert!(nan.to_degrees().is_nan()); - assert_eq!(inf.to_degrees(), inf); - assert_eq!(neg_inf.to_degrees(), neg_inf); - assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703); - } - - #[test] - fn test_to_radians() { - let pi: f32 = consts::PI; - let nan: f32 = f32::NAN; - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(0.0f32.to_radians(), 0.0); - assert_approx_eq!(154.6f32.to_radians(), 2.698279); - assert_approx_eq!((-332.31f32).to_radians(), -5.799903); - assert_eq!(180.0f32.to_radians(), pi); - assert!(nan.to_radians().is_nan()); - assert_eq!(inf.to_radians(), inf); - assert_eq!(neg_inf.to_radians(), neg_inf); - } - - #[test] - fn test_asinh() { - assert_eq!(0.0f32.asinh(), 0.0f32); - assert_eq!((-0.0f32).asinh(), -0.0f32); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf.asinh(), inf); - assert_eq!(neg_inf.asinh(), neg_inf); - assert!(nan.asinh().is_nan()); - assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271 - assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32); - assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32); - // regression test for the catastrophic cancellation fixed in 72486 - assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32); - } - - #[test] - fn test_acosh() { - assert_eq!(1.0f32.acosh(), 0.0f32); - assert!(0.999f32.acosh().is_nan()); - - let inf: f32 = f32::INFINITY; - let neg_inf: f32 = f32::NEG_INFINITY; - let nan: f32 = f32::NAN; - assert_eq!(inf.acosh(), inf); - assert!(neg_inf.acosh().is_nan()); - assert!(nan.acosh().is_nan()); - assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32); - assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32); - } - - #[test] - fn test_atanh() { - assert_eq!(0.0f32.atanh(), 0.0f32); - assert_eq!((-0.0f32).atanh(), -0.0f32); - - let inf32: f32 = f32::INFINITY; - let neg_inf32: f32 = f32::NEG_INFINITY; - assert_eq!(1.0f32.atanh(), inf32); - assert_eq!((-1.0f32).atanh(), neg_inf32); - - assert!(2f64.atanh().atanh().is_nan()); - assert!((-2f64).atanh().atanh().is_nan()); - - let inf64: f32 = f32::INFINITY; - let neg_inf64: f32 = f32::NEG_INFINITY; - let nan32: f32 = f32::NAN; - assert!(inf64.atanh().is_nan()); - assert!(neg_inf64.atanh().is_nan()); - assert!(nan32.atanh().is_nan()); - - assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); - assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32); - } - - #[test] - fn test_real_consts() { - use super::consts; - - let pi: f32 = consts::PI; - let frac_pi_2: f32 = consts::FRAC_PI_2; - let frac_pi_3: f32 = consts::FRAC_PI_3; - let frac_pi_4: f32 = consts::FRAC_PI_4; - let frac_pi_6: f32 = consts::FRAC_PI_6; - let frac_pi_8: f32 = consts::FRAC_PI_8; - let frac_1_pi: f32 = consts::FRAC_1_PI; - let frac_2_pi: f32 = consts::FRAC_2_PI; - let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI; - let sqrt2: f32 = consts::SQRT_2; - let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2; - let e: f32 = consts::E; - let log2_e: f32 = consts::LOG2_E; - let log10_e: f32 = consts::LOG10_E; - let ln_2: f32 = consts::LN_2; - let ln_10: f32 = consts::LN_10; - - assert_approx_eq!(frac_pi_2, pi / 2f32); - assert_approx_eq!(frac_pi_3, pi / 3f32); - assert_approx_eq!(frac_pi_4, pi / 4f32); - assert_approx_eq!(frac_pi_6, pi / 6f32); - assert_approx_eq!(frac_pi_8, pi / 8f32); - assert_approx_eq!(frac_1_pi, 1f32 / pi); - assert_approx_eq!(frac_2_pi, 2f32 / pi); - assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt()); - assert_approx_eq!(sqrt2, 2f32.sqrt()); - assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt()); - assert_approx_eq!(log2_e, e.log2()); - assert_approx_eq!(log10_e, e.log10()); - assert_approx_eq!(ln_2, 2f32.ln()); - assert_approx_eq!(ln_10, 10f32.ln()); - } - - #[test] - fn test_float_bits_conv() { - assert_eq!((1f32).to_bits(), 0x3f800000); - assert_eq!((12.5f32).to_bits(), 0x41480000); - assert_eq!((1337f32).to_bits(), 0x44a72000); - assert_eq!((-14.25f32).to_bits(), 0xc1640000); - assert_approx_eq!(f32::from_bits(0x3f800000), 1.0); - assert_approx_eq!(f32::from_bits(0x41480000), 12.5); - assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0); - assert_approx_eq!(f32::from_bits(0xc1640000), -14.25); - - // Check that NaNs roundtrip their bits regardless of signaling-ness - // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits - let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA; - let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555; - assert!(f32::from_bits(masked_nan1).is_nan()); - assert!(f32::from_bits(masked_nan2).is_nan()); - - assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1); - assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2); - } - - #[test] - #[should_panic] - fn test_clamp_min_greater_than_max() { - let _ = 1.0f32.clamp(3.0, 1.0); - } - - #[test] - #[should_panic] - fn test_clamp_min_is_nan() { - let _ = 1.0f32.clamp(f32::NAN, 1.0); - } - - #[test] - #[should_panic] - fn test_clamp_max_is_nan() { - let _ = 1.0f32.clamp(3.0, f32::NAN); - } - - #[test] - fn test_total_cmp() { - use core::cmp::Ordering; - - fn quiet_bit_mask() -> u32 { - 1 << (f32::MANTISSA_DIGITS - 2) - } - - fn min_subnorm() -> f32 { - f32::MIN_POSITIVE / f32::powf(2.0, f32::MANTISSA_DIGITS as f32 - 1.0) - } - - fn max_subnorm() -> f32 { - f32::MIN_POSITIVE - min_subnorm() - } - - fn q_nan() -> f32 { - f32::from_bits(f32::NAN.to_bits() | quiet_bit_mask()) - } - - fn s_nan() -> f32 { - f32::from_bits((f32::NAN.to_bits() & !quiet_bit_mask()) + 42) - } - - assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan())); - assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan())); - assert_eq!(Ordering::Equal, (-f32::INFINITY).total_cmp(&-f32::INFINITY)); - assert_eq!(Ordering::Equal, (-f32::MAX).total_cmp(&-f32::MAX)); - assert_eq!(Ordering::Equal, (-2.5_f32).total_cmp(&-2.5)); - assert_eq!(Ordering::Equal, (-1.0_f32).total_cmp(&-1.0)); - assert_eq!(Ordering::Equal, (-1.5_f32).total_cmp(&-1.5)); - assert_eq!(Ordering::Equal, (-0.5_f32).total_cmp(&-0.5)); - assert_eq!(Ordering::Equal, (-f32::MIN_POSITIVE).total_cmp(&-f32::MIN_POSITIVE)); - assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Equal, (-0.0_f32).total_cmp(&-0.0)); - assert_eq!(Ordering::Equal, 0.0_f32.total_cmp(&0.0)); - assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm())); - assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm())); - assert_eq!(Ordering::Equal, f32::MIN_POSITIVE.total_cmp(&f32::MIN_POSITIVE)); - assert_eq!(Ordering::Equal, 0.5_f32.total_cmp(&0.5)); - assert_eq!(Ordering::Equal, 1.0_f32.total_cmp(&1.0)); - assert_eq!(Ordering::Equal, 1.5_f32.total_cmp(&1.5)); - assert_eq!(Ordering::Equal, 2.5_f32.total_cmp(&2.5)); - assert_eq!(Ordering::Equal, f32::MAX.total_cmp(&f32::MAX)); - assert_eq!(Ordering::Equal, f32::INFINITY.total_cmp(&f32::INFINITY)); - assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan())); - assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan())); - - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY)); - assert_eq!(Ordering::Less, (-f32::INFINITY).total_cmp(&-f32::MAX)); - assert_eq!(Ordering::Less, (-f32::MAX).total_cmp(&-2.5)); - assert_eq!(Ordering::Less, (-2.5_f32).total_cmp(&-1.5)); - assert_eq!(Ordering::Less, (-1.5_f32).total_cmp(&-1.0)); - assert_eq!(Ordering::Less, (-1.0_f32).total_cmp(&-0.5)); - assert_eq!(Ordering::Less, (-0.5_f32).total_cmp(&-f32::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-f32::MIN_POSITIVE).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0)); - assert_eq!(Ordering::Less, (-0.0_f32).total_cmp(&0.0)); - assert_eq!(Ordering::Less, 0.0_f32.total_cmp(&min_subnorm())); - assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm())); - assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f32::MIN_POSITIVE)); - assert_eq!(Ordering::Less, f32::MIN_POSITIVE.total_cmp(&0.5)); - assert_eq!(Ordering::Less, 0.5_f32.total_cmp(&1.0)); - assert_eq!(Ordering::Less, 1.0_f32.total_cmp(&1.5)); - assert_eq!(Ordering::Less, 1.5_f32.total_cmp(&2.5)); - assert_eq!(Ordering::Less, 2.5_f32.total_cmp(&f32::MAX)); - assert_eq!(Ordering::Less, f32::MAX.total_cmp(&f32::INFINITY)); - assert_eq!(Ordering::Less, f32::INFINITY.total_cmp(&s_nan())); - assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan())); - - assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan())); - assert_eq!(Ordering::Greater, (-f32::INFINITY).total_cmp(&-s_nan())); - assert_eq!(Ordering::Greater, (-f32::MAX).total_cmp(&-f32::INFINITY)); - assert_eq!(Ordering::Greater, (-2.5_f32).total_cmp(&-f32::MAX)); - assert_eq!(Ordering::Greater, (-1.5_f32).total_cmp(&-2.5)); - assert_eq!(Ordering::Greater, (-1.0_f32).total_cmp(&-1.5)); - assert_eq!(Ordering::Greater, (-0.5_f32).total_cmp(&-1.0)); - assert_eq!(Ordering::Greater, (-f32::MIN_POSITIVE).total_cmp(&-0.5)); - assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f32::MIN_POSITIVE)); - assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Greater, (-0.0_f32).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Greater, 0.0_f32.total_cmp(&-0.0)); - assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0)); - assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm())); - assert_eq!(Ordering::Greater, f32::MIN_POSITIVE.total_cmp(&max_subnorm())); - assert_eq!(Ordering::Greater, 0.5_f32.total_cmp(&f32::MIN_POSITIVE)); - assert_eq!(Ordering::Greater, 1.0_f32.total_cmp(&0.5)); - assert_eq!(Ordering::Greater, 1.5_f32.total_cmp(&1.0)); - assert_eq!(Ordering::Greater, 2.5_f32.total_cmp(&1.5)); - assert_eq!(Ordering::Greater, f32::MAX.total_cmp(&2.5)); - assert_eq!(Ordering::Greater, f32::INFINITY.total_cmp(&f32::MAX)); - assert_eq!(Ordering::Greater, s_nan().total_cmp(&f32::INFINITY)); - assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan())); - - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::INFINITY)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MAX)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MAX)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::INFINITY)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan())); - - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MAX)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MAX)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan())); - } -} diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs new file mode 100644 index 00000000000..0d4b865f339 --- /dev/null +++ b/library/std/src/f32/tests.rs @@ -0,0 +1,759 @@ +use crate::f32::consts; +use crate::num::FpCategory as Fp; +use crate::num::*; + +#[test] +fn test_num_f32() { + test_num(10f32, 2f32); +} + +#[test] +fn test_min_nan() { + assert_eq!(f32::NAN.min(2.0), 2.0); + assert_eq!(2.0f32.min(f32::NAN), 2.0); +} + +#[test] +fn test_max_nan() { + assert_eq!(f32::NAN.max(2.0), 2.0); + assert_eq!(2.0f32.max(f32::NAN), 2.0); +} + +#[test] +fn test_nan() { + let nan: f32 = f32::NAN; + assert!(nan.is_nan()); + assert!(!nan.is_infinite()); + assert!(!nan.is_finite()); + assert!(!nan.is_normal()); + assert!(nan.is_sign_positive()); + assert!(!nan.is_sign_negative()); + assert_eq!(Fp::Nan, nan.classify()); +} + +#[test] +fn test_infinity() { + let inf: f32 = f32::INFINITY; + assert!(inf.is_infinite()); + assert!(!inf.is_finite()); + assert!(inf.is_sign_positive()); + assert!(!inf.is_sign_negative()); + assert!(!inf.is_nan()); + assert!(!inf.is_normal()); + assert_eq!(Fp::Infinite, inf.classify()); +} + +#[test] +fn test_neg_infinity() { + let neg_inf: f32 = f32::NEG_INFINITY; + assert!(neg_inf.is_infinite()); + assert!(!neg_inf.is_finite()); + assert!(!neg_inf.is_sign_positive()); + assert!(neg_inf.is_sign_negative()); + assert!(!neg_inf.is_nan()); + assert!(!neg_inf.is_normal()); + assert_eq!(Fp::Infinite, neg_inf.classify()); +} + +#[test] +fn test_zero() { + let zero: f32 = 0.0f32; + assert_eq!(0.0, zero); + assert!(!zero.is_infinite()); + assert!(zero.is_finite()); + assert!(zero.is_sign_positive()); + assert!(!zero.is_sign_negative()); + assert!(!zero.is_nan()); + assert!(!zero.is_normal()); + assert_eq!(Fp::Zero, zero.classify()); +} + +#[test] +fn test_neg_zero() { + let neg_zero: f32 = -0.0; + assert_eq!(0.0, neg_zero); + assert!(!neg_zero.is_infinite()); + assert!(neg_zero.is_finite()); + assert!(!neg_zero.is_sign_positive()); + assert!(neg_zero.is_sign_negative()); + assert!(!neg_zero.is_nan()); + assert!(!neg_zero.is_normal()); + assert_eq!(Fp::Zero, neg_zero.classify()); +} + +#[test] +fn test_one() { + let one: f32 = 1.0f32; + assert_eq!(1.0, one); + assert!(!one.is_infinite()); + assert!(one.is_finite()); + assert!(one.is_sign_positive()); + assert!(!one.is_sign_negative()); + assert!(!one.is_nan()); + assert!(one.is_normal()); + assert_eq!(Fp::Normal, one.classify()); +} + +#[test] +fn test_is_nan() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert!(nan.is_nan()); + assert!(!0.0f32.is_nan()); + assert!(!5.3f32.is_nan()); + assert!(!(-10.732f32).is_nan()); + assert!(!inf.is_nan()); + assert!(!neg_inf.is_nan()); +} + +#[test] +fn test_is_infinite() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert!(!nan.is_infinite()); + assert!(inf.is_infinite()); + assert!(neg_inf.is_infinite()); + assert!(!0.0f32.is_infinite()); + assert!(!42.8f32.is_infinite()); + assert!(!(-109.2f32).is_infinite()); +} + +#[test] +fn test_is_finite() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert!(!nan.is_finite()); + assert!(!inf.is_finite()); + assert!(!neg_inf.is_finite()); + assert!(0.0f32.is_finite()); + assert!(42.8f32.is_finite()); + assert!((-109.2f32).is_finite()); +} + +#[test] +fn test_is_normal() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + let zero: f32 = 0.0f32; + let neg_zero: f32 = -0.0; + assert!(!nan.is_normal()); + assert!(!inf.is_normal()); + assert!(!neg_inf.is_normal()); + assert!(!zero.is_normal()); + assert!(!neg_zero.is_normal()); + assert!(1f32.is_normal()); + assert!(1e-37f32.is_normal()); + assert!(!1e-38f32.is_normal()); +} + +#[test] +fn test_classify() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + let zero: f32 = 0.0f32; + let neg_zero: f32 = -0.0; + assert_eq!(nan.classify(), Fp::Nan); + assert_eq!(inf.classify(), Fp::Infinite); + assert_eq!(neg_inf.classify(), Fp::Infinite); + assert_eq!(zero.classify(), Fp::Zero); + assert_eq!(neg_zero.classify(), Fp::Zero); + assert_eq!(1f32.classify(), Fp::Normal); + assert_eq!(1e-37f32.classify(), Fp::Normal); + assert_eq!(1e-38f32.classify(), Fp::Subnormal); +} + +#[test] +fn test_floor() { + assert_approx_eq!(1.0f32.floor(), 1.0f32); + assert_approx_eq!(1.3f32.floor(), 1.0f32); + assert_approx_eq!(1.5f32.floor(), 1.0f32); + assert_approx_eq!(1.7f32.floor(), 1.0f32); + assert_approx_eq!(0.0f32.floor(), 0.0f32); + assert_approx_eq!((-0.0f32).floor(), -0.0f32); + assert_approx_eq!((-1.0f32).floor(), -1.0f32); + assert_approx_eq!((-1.3f32).floor(), -2.0f32); + assert_approx_eq!((-1.5f32).floor(), -2.0f32); + assert_approx_eq!((-1.7f32).floor(), -2.0f32); +} + +#[test] +fn test_ceil() { + assert_approx_eq!(1.0f32.ceil(), 1.0f32); + assert_approx_eq!(1.3f32.ceil(), 2.0f32); + assert_approx_eq!(1.5f32.ceil(), 2.0f32); + assert_approx_eq!(1.7f32.ceil(), 2.0f32); + assert_approx_eq!(0.0f32.ceil(), 0.0f32); + assert_approx_eq!((-0.0f32).ceil(), -0.0f32); + assert_approx_eq!((-1.0f32).ceil(), -1.0f32); + assert_approx_eq!((-1.3f32).ceil(), -1.0f32); + assert_approx_eq!((-1.5f32).ceil(), -1.0f32); + assert_approx_eq!((-1.7f32).ceil(), -1.0f32); +} + +#[test] +fn test_round() { + assert_approx_eq!(1.0f32.round(), 1.0f32); + assert_approx_eq!(1.3f32.round(), 1.0f32); + assert_approx_eq!(1.5f32.round(), 2.0f32); + assert_approx_eq!(1.7f32.round(), 2.0f32); + assert_approx_eq!(0.0f32.round(), 0.0f32); + assert_approx_eq!((-0.0f32).round(), -0.0f32); + assert_approx_eq!((-1.0f32).round(), -1.0f32); + assert_approx_eq!((-1.3f32).round(), -1.0f32); + assert_approx_eq!((-1.5f32).round(), -2.0f32); + assert_approx_eq!((-1.7f32).round(), -2.0f32); +} + +#[test] +fn test_trunc() { + assert_approx_eq!(1.0f32.trunc(), 1.0f32); + assert_approx_eq!(1.3f32.trunc(), 1.0f32); + assert_approx_eq!(1.5f32.trunc(), 1.0f32); + assert_approx_eq!(1.7f32.trunc(), 1.0f32); + assert_approx_eq!(0.0f32.trunc(), 0.0f32); + assert_approx_eq!((-0.0f32).trunc(), -0.0f32); + assert_approx_eq!((-1.0f32).trunc(), -1.0f32); + assert_approx_eq!((-1.3f32).trunc(), -1.0f32); + assert_approx_eq!((-1.5f32).trunc(), -1.0f32); + assert_approx_eq!((-1.7f32).trunc(), -1.0f32); +} + +#[test] +fn test_fract() { + assert_approx_eq!(1.0f32.fract(), 0.0f32); + assert_approx_eq!(1.3f32.fract(), 0.3f32); + assert_approx_eq!(1.5f32.fract(), 0.5f32); + assert_approx_eq!(1.7f32.fract(), 0.7f32); + assert_approx_eq!(0.0f32.fract(), 0.0f32); + assert_approx_eq!((-0.0f32).fract(), -0.0f32); + assert_approx_eq!((-1.0f32).fract(), -0.0f32); + assert_approx_eq!((-1.3f32).fract(), -0.3f32); + assert_approx_eq!((-1.5f32).fract(), -0.5f32); + assert_approx_eq!((-1.7f32).fract(), -0.7f32); +} + +#[test] +fn test_abs() { + assert_eq!(f32::INFINITY.abs(), f32::INFINITY); + assert_eq!(1f32.abs(), 1f32); + assert_eq!(0f32.abs(), 0f32); + assert_eq!((-0f32).abs(), 0f32); + assert_eq!((-1f32).abs(), 1f32); + assert_eq!(f32::NEG_INFINITY.abs(), f32::INFINITY); + assert_eq!((1f32 / f32::NEG_INFINITY).abs(), 0f32); + assert!(f32::NAN.abs().is_nan()); +} + +#[test] +fn test_signum() { + assert_eq!(f32::INFINITY.signum(), 1f32); + assert_eq!(1f32.signum(), 1f32); + assert_eq!(0f32.signum(), 1f32); + assert_eq!((-0f32).signum(), -1f32); + assert_eq!((-1f32).signum(), -1f32); + assert_eq!(f32::NEG_INFINITY.signum(), -1f32); + assert_eq!((1f32 / f32::NEG_INFINITY).signum(), -1f32); + assert!(f32::NAN.signum().is_nan()); +} + +#[test] +fn test_is_sign_positive() { + assert!(f32::INFINITY.is_sign_positive()); + assert!(1f32.is_sign_positive()); + assert!(0f32.is_sign_positive()); + assert!(!(-0f32).is_sign_positive()); + assert!(!(-1f32).is_sign_positive()); + assert!(!f32::NEG_INFINITY.is_sign_positive()); + assert!(!(1f32 / f32::NEG_INFINITY).is_sign_positive()); + assert!(f32::NAN.is_sign_positive()); + assert!(!(-f32::NAN).is_sign_positive()); +} + +#[test] +fn test_is_sign_negative() { + assert!(!f32::INFINITY.is_sign_negative()); + assert!(!1f32.is_sign_negative()); + assert!(!0f32.is_sign_negative()); + assert!((-0f32).is_sign_negative()); + assert!((-1f32).is_sign_negative()); + assert!(f32::NEG_INFINITY.is_sign_negative()); + assert!((1f32 / f32::NEG_INFINITY).is_sign_negative()); + assert!(!f32::NAN.is_sign_negative()); + assert!((-f32::NAN).is_sign_negative()); +} + +#[test] +fn test_mul_add() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05); + assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65); + assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2); + assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6); + assert!(nan.mul_add(7.8, 9.0).is_nan()); + assert_eq!(inf.mul_add(7.8, 9.0), inf); + assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf); + assert_eq!(8.9f32.mul_add(inf, 3.2), inf); + assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf); +} + +#[test] +fn test_recip() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(1.0f32.recip(), 1.0); + assert_eq!(2.0f32.recip(), 0.5); + assert_eq!((-0.4f32).recip(), -2.5); + assert_eq!(0.0f32.recip(), inf); + assert!(nan.recip().is_nan()); + assert_eq!(inf.recip(), 0.0); + assert_eq!(neg_inf.recip(), 0.0); +} + +#[test] +fn test_powi() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(1.0f32.powi(1), 1.0); + assert_approx_eq!((-3.1f32).powi(2), 9.61); + assert_approx_eq!(5.9f32.powi(-2), 0.028727); + assert_eq!(8.3f32.powi(0), 1.0); + assert!(nan.powi(2).is_nan()); + assert_eq!(inf.powi(3), inf); + assert_eq!(neg_inf.powi(2), inf); +} + +#[test] +fn test_powf() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(1.0f32.powf(1.0), 1.0); + assert_approx_eq!(3.4f32.powf(4.5), 246.408218); + assert_approx_eq!(2.7f32.powf(-3.2), 0.041652); + assert_approx_eq!((-3.1f32).powf(2.0), 9.61); + assert_approx_eq!(5.9f32.powf(-2.0), 0.028727); + assert_eq!(8.3f32.powf(0.0), 1.0); + assert!(nan.powf(2.0).is_nan()); + assert_eq!(inf.powf(2.0), inf); + assert_eq!(neg_inf.powf(3.0), neg_inf); +} + +#[test] +fn test_sqrt_domain() { + assert!(f32::NAN.sqrt().is_nan()); + assert!(f32::NEG_INFINITY.sqrt().is_nan()); + assert!((-1.0f32).sqrt().is_nan()); + assert_eq!((-0.0f32).sqrt(), -0.0); + assert_eq!(0.0f32.sqrt(), 0.0); + assert_eq!(1.0f32.sqrt(), 1.0); + assert_eq!(f32::INFINITY.sqrt(), f32::INFINITY); +} + +#[test] +fn test_exp() { + assert_eq!(1.0, 0.0f32.exp()); + assert_approx_eq!(2.718282, 1.0f32.exp()); + assert_approx_eq!(148.413162, 5.0f32.exp()); + + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + let nan: f32 = f32::NAN; + assert_eq!(inf, inf.exp()); + assert_eq!(0.0, neg_inf.exp()); + assert!(nan.exp().is_nan()); +} + +#[test] +fn test_exp2() { + assert_eq!(32.0, 5.0f32.exp2()); + assert_eq!(1.0, 0.0f32.exp2()); + + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + let nan: f32 = f32::NAN; + assert_eq!(inf, inf.exp2()); + assert_eq!(0.0, neg_inf.exp2()); + assert!(nan.exp2().is_nan()); +} + +#[test] +fn test_ln() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_approx_eq!(1.0f32.exp().ln(), 1.0); + assert!(nan.ln().is_nan()); + assert_eq!(inf.ln(), inf); + assert!(neg_inf.ln().is_nan()); + assert!((-2.3f32).ln().is_nan()); + assert_eq!((-0.0f32).ln(), neg_inf); + assert_eq!(0.0f32.ln(), neg_inf); + assert_approx_eq!(4.0f32.ln(), 1.386294); +} + +#[test] +fn test_log() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(10.0f32.log(10.0), 1.0); + assert_approx_eq!(2.3f32.log(3.5), 0.664858); + assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0); + assert!(1.0f32.log(1.0).is_nan()); + assert!(1.0f32.log(-13.9).is_nan()); + assert!(nan.log(2.3).is_nan()); + assert_eq!(inf.log(10.0), inf); + assert!(neg_inf.log(8.8).is_nan()); + assert!((-2.3f32).log(0.1).is_nan()); + assert_eq!((-0.0f32).log(2.0), neg_inf); + assert_eq!(0.0f32.log(7.0), neg_inf); +} + +#[test] +fn test_log2() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_approx_eq!(10.0f32.log2(), 3.321928); + assert_approx_eq!(2.3f32.log2(), 1.201634); + assert_approx_eq!(1.0f32.exp().log2(), 1.442695); + assert!(nan.log2().is_nan()); + assert_eq!(inf.log2(), inf); + assert!(neg_inf.log2().is_nan()); + assert!((-2.3f32).log2().is_nan()); + assert_eq!((-0.0f32).log2(), neg_inf); + assert_eq!(0.0f32.log2(), neg_inf); +} + +#[test] +fn test_log10() { + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(10.0f32.log10(), 1.0); + assert_approx_eq!(2.3f32.log10(), 0.361728); + assert_approx_eq!(1.0f32.exp().log10(), 0.434294); + assert_eq!(1.0f32.log10(), 0.0); + assert!(nan.log10().is_nan()); + assert_eq!(inf.log10(), inf); + assert!(neg_inf.log10().is_nan()); + assert!((-2.3f32).log10().is_nan()); + assert_eq!((-0.0f32).log10(), neg_inf); + assert_eq!(0.0f32.log10(), neg_inf); +} + +#[test] +fn test_to_degrees() { + let pi: f32 = consts::PI; + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(0.0f32.to_degrees(), 0.0); + assert_approx_eq!((-5.8f32).to_degrees(), -332.315521); + assert_eq!(pi.to_degrees(), 180.0); + assert!(nan.to_degrees().is_nan()); + assert_eq!(inf.to_degrees(), inf); + assert_eq!(neg_inf.to_degrees(), neg_inf); + assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703); +} + +#[test] +fn test_to_radians() { + let pi: f32 = consts::PI; + let nan: f32 = f32::NAN; + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + assert_eq!(0.0f32.to_radians(), 0.0); + assert_approx_eq!(154.6f32.to_radians(), 2.698279); + assert_approx_eq!((-332.31f32).to_radians(), -5.799903); + assert_eq!(180.0f32.to_radians(), pi); + assert!(nan.to_radians().is_nan()); + assert_eq!(inf.to_radians(), inf); + assert_eq!(neg_inf.to_radians(), neg_inf); +} + +#[test] +fn test_asinh() { + assert_eq!(0.0f32.asinh(), 0.0f32); + assert_eq!((-0.0f32).asinh(), -0.0f32); + + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + let nan: f32 = f32::NAN; + assert_eq!(inf.asinh(), inf); + assert_eq!(neg_inf.asinh(), neg_inf); + assert!(nan.asinh().is_nan()); + assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271 + assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32); + assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32); + // regression test for the catastrophic cancellation fixed in 72486 + assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32); +} + +#[test] +fn test_acosh() { + assert_eq!(1.0f32.acosh(), 0.0f32); + assert!(0.999f32.acosh().is_nan()); + + let inf: f32 = f32::INFINITY; + let neg_inf: f32 = f32::NEG_INFINITY; + let nan: f32 = f32::NAN; + assert_eq!(inf.acosh(), inf); + assert!(neg_inf.acosh().is_nan()); + assert!(nan.acosh().is_nan()); + assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32); + assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32); +} + +#[test] +fn test_atanh() { + assert_eq!(0.0f32.atanh(), 0.0f32); + assert_eq!((-0.0f32).atanh(), -0.0f32); + + let inf32: f32 = f32::INFINITY; + let neg_inf32: f32 = f32::NEG_INFINITY; + assert_eq!(1.0f32.atanh(), inf32); + assert_eq!((-1.0f32).atanh(), neg_inf32); + + assert!(2f64.atanh().atanh().is_nan()); + assert!((-2f64).atanh().atanh().is_nan()); + + let inf64: f32 = f32::INFINITY; + let neg_inf64: f32 = f32::NEG_INFINITY; + let nan32: f32 = f32::NAN; + assert!(inf64.atanh().is_nan()); + assert!(neg_inf64.atanh().is_nan()); + assert!(nan32.atanh().is_nan()); + + assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); + assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32); +} + +#[test] +fn test_real_consts() { + use super::consts; + + let pi: f32 = consts::PI; + let frac_pi_2: f32 = consts::FRAC_PI_2; + let frac_pi_3: f32 = consts::FRAC_PI_3; + let frac_pi_4: f32 = consts::FRAC_PI_4; + let frac_pi_6: f32 = consts::FRAC_PI_6; + let frac_pi_8: f32 = consts::FRAC_PI_8; + let frac_1_pi: f32 = consts::FRAC_1_PI; + let frac_2_pi: f32 = consts::FRAC_2_PI; + let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI; + let sqrt2: f32 = consts::SQRT_2; + let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2; + let e: f32 = consts::E; + let log2_e: f32 = consts::LOG2_E; + let log10_e: f32 = consts::LOG10_E; + let ln_2: f32 = consts::LN_2; + let ln_10: f32 = consts::LN_10; + + assert_approx_eq!(frac_pi_2, pi / 2f32); + assert_approx_eq!(frac_pi_3, pi / 3f32); + assert_approx_eq!(frac_pi_4, pi / 4f32); + assert_approx_eq!(frac_pi_6, pi / 6f32); + assert_approx_eq!(frac_pi_8, pi / 8f32); + assert_approx_eq!(frac_1_pi, 1f32 / pi); + assert_approx_eq!(frac_2_pi, 2f32 / pi); + assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt()); + assert_approx_eq!(sqrt2, 2f32.sqrt()); + assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt()); + assert_approx_eq!(log2_e, e.log2()); + assert_approx_eq!(log10_e, e.log10()); + assert_approx_eq!(ln_2, 2f32.ln()); + assert_approx_eq!(ln_10, 10f32.ln()); +} + +#[test] +fn test_float_bits_conv() { + assert_eq!((1f32).to_bits(), 0x3f800000); + assert_eq!((12.5f32).to_bits(), 0x41480000); + assert_eq!((1337f32).to_bits(), 0x44a72000); + assert_eq!((-14.25f32).to_bits(), 0xc1640000); + assert_approx_eq!(f32::from_bits(0x3f800000), 1.0); + assert_approx_eq!(f32::from_bits(0x41480000), 12.5); + assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0); + assert_approx_eq!(f32::from_bits(0xc1640000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signaling-ness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA; + let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555; + assert!(f32::from_bits(masked_nan1).is_nan()); + assert!(f32::from_bits(masked_nan2).is_nan()); + + assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1); + assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2); +} + +#[test] +#[should_panic] +fn test_clamp_min_greater_than_max() { + let _ = 1.0f32.clamp(3.0, 1.0); +} + +#[test] +#[should_panic] +fn test_clamp_min_is_nan() { + let _ = 1.0f32.clamp(f32::NAN, 1.0); +} + +#[test] +#[should_panic] +fn test_clamp_max_is_nan() { + let _ = 1.0f32.clamp(3.0, f32::NAN); +} + +#[test] +fn test_total_cmp() { + use core::cmp::Ordering; + + fn quiet_bit_mask() -> u32 { + 1 << (f32::MANTISSA_DIGITS - 2) + } + + fn min_subnorm() -> f32 { + f32::MIN_POSITIVE / f32::powf(2.0, f32::MANTISSA_DIGITS as f32 - 1.0) + } + + fn max_subnorm() -> f32 { + f32::MIN_POSITIVE - min_subnorm() + } + + fn q_nan() -> f32 { + f32::from_bits(f32::NAN.to_bits() | quiet_bit_mask()) + } + + fn s_nan() -> f32 { + f32::from_bits((f32::NAN.to_bits() & !quiet_bit_mask()) + 42) + } + + assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan())); + assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan())); + assert_eq!(Ordering::Equal, (-f32::INFINITY).total_cmp(&-f32::INFINITY)); + assert_eq!(Ordering::Equal, (-f32::MAX).total_cmp(&-f32::MAX)); + assert_eq!(Ordering::Equal, (-2.5_f32).total_cmp(&-2.5)); + assert_eq!(Ordering::Equal, (-1.0_f32).total_cmp(&-1.0)); + assert_eq!(Ordering::Equal, (-1.5_f32).total_cmp(&-1.5)); + assert_eq!(Ordering::Equal, (-0.5_f32).total_cmp(&-0.5)); + assert_eq!(Ordering::Equal, (-f32::MIN_POSITIVE).total_cmp(&-f32::MIN_POSITIVE)); + assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Equal, (-0.0_f32).total_cmp(&-0.0)); + assert_eq!(Ordering::Equal, 0.0_f32.total_cmp(&0.0)); + assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm())); + assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm())); + assert_eq!(Ordering::Equal, f32::MIN_POSITIVE.total_cmp(&f32::MIN_POSITIVE)); + assert_eq!(Ordering::Equal, 0.5_f32.total_cmp(&0.5)); + assert_eq!(Ordering::Equal, 1.0_f32.total_cmp(&1.0)); + assert_eq!(Ordering::Equal, 1.5_f32.total_cmp(&1.5)); + assert_eq!(Ordering::Equal, 2.5_f32.total_cmp(&2.5)); + assert_eq!(Ordering::Equal, f32::MAX.total_cmp(&f32::MAX)); + assert_eq!(Ordering::Equal, f32::INFINITY.total_cmp(&f32::INFINITY)); + assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan())); + assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan())); + + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY)); + assert_eq!(Ordering::Less, (-f32::INFINITY).total_cmp(&-f32::MAX)); + assert_eq!(Ordering::Less, (-f32::MAX).total_cmp(&-2.5)); + assert_eq!(Ordering::Less, (-2.5_f32).total_cmp(&-1.5)); + assert_eq!(Ordering::Less, (-1.5_f32).total_cmp(&-1.0)); + assert_eq!(Ordering::Less, (-1.0_f32).total_cmp(&-0.5)); + assert_eq!(Ordering::Less, (-0.5_f32).total_cmp(&-f32::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-f32::MIN_POSITIVE).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-0.0_f32).total_cmp(&0.0)); + assert_eq!(Ordering::Less, 0.0_f32.total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f32::MIN_POSITIVE)); + assert_eq!(Ordering::Less, f32::MIN_POSITIVE.total_cmp(&0.5)); + assert_eq!(Ordering::Less, 0.5_f32.total_cmp(&1.0)); + assert_eq!(Ordering::Less, 1.0_f32.total_cmp(&1.5)); + assert_eq!(Ordering::Less, 1.5_f32.total_cmp(&2.5)); + assert_eq!(Ordering::Less, 2.5_f32.total_cmp(&f32::MAX)); + assert_eq!(Ordering::Less, f32::MAX.total_cmp(&f32::INFINITY)); + assert_eq!(Ordering::Less, f32::INFINITY.total_cmp(&s_nan())); + assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan())); + + assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan())); + assert_eq!(Ordering::Greater, (-f32::INFINITY).total_cmp(&-s_nan())); + assert_eq!(Ordering::Greater, (-f32::MAX).total_cmp(&-f32::INFINITY)); + assert_eq!(Ordering::Greater, (-2.5_f32).total_cmp(&-f32::MAX)); + assert_eq!(Ordering::Greater, (-1.5_f32).total_cmp(&-2.5)); + assert_eq!(Ordering::Greater, (-1.0_f32).total_cmp(&-1.5)); + assert_eq!(Ordering::Greater, (-0.5_f32).total_cmp(&-1.0)); + assert_eq!(Ordering::Greater, (-f32::MIN_POSITIVE).total_cmp(&-0.5)); + assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f32::MIN_POSITIVE)); + assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Greater, (-0.0_f32).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Greater, 0.0_f32.total_cmp(&-0.0)); + assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0)); + assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm())); + assert_eq!(Ordering::Greater, f32::MIN_POSITIVE.total_cmp(&max_subnorm())); + assert_eq!(Ordering::Greater, 0.5_f32.total_cmp(&f32::MIN_POSITIVE)); + assert_eq!(Ordering::Greater, 1.0_f32.total_cmp(&0.5)); + assert_eq!(Ordering::Greater, 1.5_f32.total_cmp(&1.0)); + assert_eq!(Ordering::Greater, 2.5_f32.total_cmp(&1.5)); + assert_eq!(Ordering::Greater, f32::MAX.total_cmp(&2.5)); + assert_eq!(Ordering::Greater, f32::INFINITY.total_cmp(&f32::MAX)); + assert_eq!(Ordering::Greater, s_nan().total_cmp(&f32::INFINITY)); + assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan())); + + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::INFINITY)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MAX)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f32::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::MAX)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f32::INFINITY)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan())); + + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::INFINITY)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MAX)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f32::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::MAX)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan())); +} diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index f09fc8d790b..bd094bdb55d 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -11,6 +11,9 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] +#[cfg(test)] +mod tests; + #[cfg(not(test))] use crate::intrinsics; #[cfg(not(test))] @@ -936,762 +939,3 @@ impl f64 { } } } - -#[cfg(test)] -mod tests { - use crate::f64::consts; - use crate::num::FpCategory as Fp; - use crate::num::*; - - #[test] - fn test_num_f64() { - test_num(10f64, 2f64); - } - - #[test] - fn test_min_nan() { - assert_eq!(f64::NAN.min(2.0), 2.0); - assert_eq!(2.0f64.min(f64::NAN), 2.0); - } - - #[test] - fn test_max_nan() { - assert_eq!(f64::NAN.max(2.0), 2.0); - assert_eq!(2.0f64.max(f64::NAN), 2.0); - } - - #[test] - fn test_nan() { - let nan: f64 = f64::NAN; - assert!(nan.is_nan()); - assert!(!nan.is_infinite()); - assert!(!nan.is_finite()); - assert!(!nan.is_normal()); - assert!(nan.is_sign_positive()); - assert!(!nan.is_sign_negative()); - assert_eq!(Fp::Nan, nan.classify()); - } - - #[test] - fn test_infinity() { - let inf: f64 = f64::INFINITY; - assert!(inf.is_infinite()); - assert!(!inf.is_finite()); - assert!(inf.is_sign_positive()); - assert!(!inf.is_sign_negative()); - assert!(!inf.is_nan()); - assert!(!inf.is_normal()); - assert_eq!(Fp::Infinite, inf.classify()); - } - - #[test] - fn test_neg_infinity() { - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(neg_inf.is_infinite()); - assert!(!neg_inf.is_finite()); - assert!(!neg_inf.is_sign_positive()); - assert!(neg_inf.is_sign_negative()); - assert!(!neg_inf.is_nan()); - assert!(!neg_inf.is_normal()); - assert_eq!(Fp::Infinite, neg_inf.classify()); - } - - #[test] - fn test_zero() { - let zero: f64 = 0.0f64; - assert_eq!(0.0, zero); - assert!(!zero.is_infinite()); - assert!(zero.is_finite()); - assert!(zero.is_sign_positive()); - assert!(!zero.is_sign_negative()); - assert!(!zero.is_nan()); - assert!(!zero.is_normal()); - assert_eq!(Fp::Zero, zero.classify()); - } - - #[test] - fn test_neg_zero() { - let neg_zero: f64 = -0.0; - assert_eq!(0.0, neg_zero); - assert!(!neg_zero.is_infinite()); - assert!(neg_zero.is_finite()); - assert!(!neg_zero.is_sign_positive()); - assert!(neg_zero.is_sign_negative()); - assert!(!neg_zero.is_nan()); - assert!(!neg_zero.is_normal()); - assert_eq!(Fp::Zero, neg_zero.classify()); - } - - #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 - #[test] - fn test_one() { - let one: f64 = 1.0f64; - assert_eq!(1.0, one); - assert!(!one.is_infinite()); - assert!(one.is_finite()); - assert!(one.is_sign_positive()); - assert!(!one.is_sign_negative()); - assert!(!one.is_nan()); - assert!(one.is_normal()); - assert_eq!(Fp::Normal, one.classify()); - } - - #[test] - fn test_is_nan() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(nan.is_nan()); - assert!(!0.0f64.is_nan()); - assert!(!5.3f64.is_nan()); - assert!(!(-10.732f64).is_nan()); - assert!(!inf.is_nan()); - assert!(!neg_inf.is_nan()); - } - - #[test] - fn test_is_infinite() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(!nan.is_infinite()); - assert!(inf.is_infinite()); - assert!(neg_inf.is_infinite()); - assert!(!0.0f64.is_infinite()); - assert!(!42.8f64.is_infinite()); - assert!(!(-109.2f64).is_infinite()); - } - - #[test] - fn test_is_finite() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert!(!nan.is_finite()); - assert!(!inf.is_finite()); - assert!(!neg_inf.is_finite()); - assert!(0.0f64.is_finite()); - assert!(42.8f64.is_finite()); - assert!((-109.2f64).is_finite()); - } - - #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 - #[test] - fn test_is_normal() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let zero: f64 = 0.0f64; - let neg_zero: f64 = -0.0; - assert!(!nan.is_normal()); - assert!(!inf.is_normal()); - assert!(!neg_inf.is_normal()); - assert!(!zero.is_normal()); - assert!(!neg_zero.is_normal()); - assert!(1f64.is_normal()); - assert!(1e-307f64.is_normal()); - assert!(!1e-308f64.is_normal()); - } - - #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 - #[test] - fn test_classify() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let zero: f64 = 0.0f64; - let neg_zero: f64 = -0.0; - assert_eq!(nan.classify(), Fp::Nan); - assert_eq!(inf.classify(), Fp::Infinite); - assert_eq!(neg_inf.classify(), Fp::Infinite); - assert_eq!(zero.classify(), Fp::Zero); - assert_eq!(neg_zero.classify(), Fp::Zero); - assert_eq!(1e-307f64.classify(), Fp::Normal); - assert_eq!(1e-308f64.classify(), Fp::Subnormal); - } - - #[test] - fn test_floor() { - assert_approx_eq!(1.0f64.floor(), 1.0f64); - assert_approx_eq!(1.3f64.floor(), 1.0f64); - assert_approx_eq!(1.5f64.floor(), 1.0f64); - assert_approx_eq!(1.7f64.floor(), 1.0f64); - assert_approx_eq!(0.0f64.floor(), 0.0f64); - assert_approx_eq!((-0.0f64).floor(), -0.0f64); - assert_approx_eq!((-1.0f64).floor(), -1.0f64); - assert_approx_eq!((-1.3f64).floor(), -2.0f64); - assert_approx_eq!((-1.5f64).floor(), -2.0f64); - assert_approx_eq!((-1.7f64).floor(), -2.0f64); - } - - #[test] - fn test_ceil() { - assert_approx_eq!(1.0f64.ceil(), 1.0f64); - assert_approx_eq!(1.3f64.ceil(), 2.0f64); - assert_approx_eq!(1.5f64.ceil(), 2.0f64); - assert_approx_eq!(1.7f64.ceil(), 2.0f64); - assert_approx_eq!(0.0f64.ceil(), 0.0f64); - assert_approx_eq!((-0.0f64).ceil(), -0.0f64); - assert_approx_eq!((-1.0f64).ceil(), -1.0f64); - assert_approx_eq!((-1.3f64).ceil(), -1.0f64); - assert_approx_eq!((-1.5f64).ceil(), -1.0f64); - assert_approx_eq!((-1.7f64).ceil(), -1.0f64); - } - - #[test] - fn test_round() { - assert_approx_eq!(1.0f64.round(), 1.0f64); - assert_approx_eq!(1.3f64.round(), 1.0f64); - assert_approx_eq!(1.5f64.round(), 2.0f64); - assert_approx_eq!(1.7f64.round(), 2.0f64); - assert_approx_eq!(0.0f64.round(), 0.0f64); - assert_approx_eq!((-0.0f64).round(), -0.0f64); - assert_approx_eq!((-1.0f64).round(), -1.0f64); - assert_approx_eq!((-1.3f64).round(), -1.0f64); - assert_approx_eq!((-1.5f64).round(), -2.0f64); - assert_approx_eq!((-1.7f64).round(), -2.0f64); - } - - #[test] - fn test_trunc() { - assert_approx_eq!(1.0f64.trunc(), 1.0f64); - assert_approx_eq!(1.3f64.trunc(), 1.0f64); - assert_approx_eq!(1.5f64.trunc(), 1.0f64); - assert_approx_eq!(1.7f64.trunc(), 1.0f64); - assert_approx_eq!(0.0f64.trunc(), 0.0f64); - assert_approx_eq!((-0.0f64).trunc(), -0.0f64); - assert_approx_eq!((-1.0f64).trunc(), -1.0f64); - assert_approx_eq!((-1.3f64).trunc(), -1.0f64); - assert_approx_eq!((-1.5f64).trunc(), -1.0f64); - assert_approx_eq!((-1.7f64).trunc(), -1.0f64); - } - - #[test] - fn test_fract() { - assert_approx_eq!(1.0f64.fract(), 0.0f64); - assert_approx_eq!(1.3f64.fract(), 0.3f64); - assert_approx_eq!(1.5f64.fract(), 0.5f64); - assert_approx_eq!(1.7f64.fract(), 0.7f64); - assert_approx_eq!(0.0f64.fract(), 0.0f64); - assert_approx_eq!((-0.0f64).fract(), -0.0f64); - assert_approx_eq!((-1.0f64).fract(), -0.0f64); - assert_approx_eq!((-1.3f64).fract(), -0.3f64); - assert_approx_eq!((-1.5f64).fract(), -0.5f64); - assert_approx_eq!((-1.7f64).fract(), -0.7f64); - } - - #[test] - fn test_abs() { - assert_eq!(f64::INFINITY.abs(), f64::INFINITY); - assert_eq!(1f64.abs(), 1f64); - assert_eq!(0f64.abs(), 0f64); - assert_eq!((-0f64).abs(), 0f64); - assert_eq!((-1f64).abs(), 1f64); - assert_eq!(f64::NEG_INFINITY.abs(), f64::INFINITY); - assert_eq!((1f64 / f64::NEG_INFINITY).abs(), 0f64); - assert!(f64::NAN.abs().is_nan()); - } - - #[test] - fn test_signum() { - assert_eq!(f64::INFINITY.signum(), 1f64); - assert_eq!(1f64.signum(), 1f64); - assert_eq!(0f64.signum(), 1f64); - assert_eq!((-0f64).signum(), -1f64); - assert_eq!((-1f64).signum(), -1f64); - assert_eq!(f64::NEG_INFINITY.signum(), -1f64); - assert_eq!((1f64 / f64::NEG_INFINITY).signum(), -1f64); - assert!(f64::NAN.signum().is_nan()); - } - - #[test] - fn test_is_sign_positive() { - assert!(f64::INFINITY.is_sign_positive()); - assert!(1f64.is_sign_positive()); - assert!(0f64.is_sign_positive()); - assert!(!(-0f64).is_sign_positive()); - assert!(!(-1f64).is_sign_positive()); - assert!(!f64::NEG_INFINITY.is_sign_positive()); - assert!(!(1f64 / f64::NEG_INFINITY).is_sign_positive()); - assert!(f64::NAN.is_sign_positive()); - assert!(!(-f64::NAN).is_sign_positive()); - } - - #[test] - fn test_is_sign_negative() { - assert!(!f64::INFINITY.is_sign_negative()); - assert!(!1f64.is_sign_negative()); - assert!(!0f64.is_sign_negative()); - assert!((-0f64).is_sign_negative()); - assert!((-1f64).is_sign_negative()); - assert!(f64::NEG_INFINITY.is_sign_negative()); - assert!((1f64 / f64::NEG_INFINITY).is_sign_negative()); - assert!(!f64::NAN.is_sign_negative()); - assert!((-f64::NAN).is_sign_negative()); - } - - #[test] - fn test_mul_add() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05); - assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65); - assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2); - assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6); - assert!(nan.mul_add(7.8, 9.0).is_nan()); - assert_eq!(inf.mul_add(7.8, 9.0), inf); - assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf); - assert_eq!(8.9f64.mul_add(inf, 3.2), inf); - assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf); - } - - #[test] - fn test_recip() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(1.0f64.recip(), 1.0); - assert_eq!(2.0f64.recip(), 0.5); - assert_eq!((-0.4f64).recip(), -2.5); - assert_eq!(0.0f64.recip(), inf); - assert!(nan.recip().is_nan()); - assert_eq!(inf.recip(), 0.0); - assert_eq!(neg_inf.recip(), 0.0); - } - - #[test] - fn test_powi() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(1.0f64.powi(1), 1.0); - assert_approx_eq!((-3.1f64).powi(2), 9.61); - assert_approx_eq!(5.9f64.powi(-2), 0.028727); - assert_eq!(8.3f64.powi(0), 1.0); - assert!(nan.powi(2).is_nan()); - assert_eq!(inf.powi(3), inf); - assert_eq!(neg_inf.powi(2), inf); - } - - #[test] - fn test_powf() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(1.0f64.powf(1.0), 1.0); - assert_approx_eq!(3.4f64.powf(4.5), 246.408183); - assert_approx_eq!(2.7f64.powf(-3.2), 0.041652); - assert_approx_eq!((-3.1f64).powf(2.0), 9.61); - assert_approx_eq!(5.9f64.powf(-2.0), 0.028727); - assert_eq!(8.3f64.powf(0.0), 1.0); - assert!(nan.powf(2.0).is_nan()); - assert_eq!(inf.powf(2.0), inf); - assert_eq!(neg_inf.powf(3.0), neg_inf); - } - - #[test] - fn test_sqrt_domain() { - assert!(f64::NAN.sqrt().is_nan()); - assert!(f64::NEG_INFINITY.sqrt().is_nan()); - assert!((-1.0f64).sqrt().is_nan()); - assert_eq!((-0.0f64).sqrt(), -0.0); - assert_eq!(0.0f64.sqrt(), 0.0); - assert_eq!(1.0f64.sqrt(), 1.0); - assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY); - } - - #[test] - fn test_exp() { - assert_eq!(1.0, 0.0f64.exp()); - assert_approx_eq!(2.718282, 1.0f64.exp()); - assert_approx_eq!(148.413159, 5.0f64.exp()); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf, inf.exp()); - assert_eq!(0.0, neg_inf.exp()); - assert!(nan.exp().is_nan()); - } - - #[test] - fn test_exp2() { - assert_eq!(32.0, 5.0f64.exp2()); - assert_eq!(1.0, 0.0f64.exp2()); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf, inf.exp2()); - assert_eq!(0.0, neg_inf.exp2()); - assert!(nan.exp2().is_nan()); - } - - #[test] - fn test_ln() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(1.0f64.exp().ln(), 1.0); - assert!(nan.ln().is_nan()); - assert_eq!(inf.ln(), inf); - assert!(neg_inf.ln().is_nan()); - assert!((-2.3f64).ln().is_nan()); - assert_eq!((-0.0f64).ln(), neg_inf); - assert_eq!(0.0f64.ln(), neg_inf); - assert_approx_eq!(4.0f64.ln(), 1.386294); - } - - #[test] - fn test_log() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(10.0f64.log(10.0), 1.0); - assert_approx_eq!(2.3f64.log(3.5), 0.664858); - assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0); - assert!(1.0f64.log(1.0).is_nan()); - assert!(1.0f64.log(-13.9).is_nan()); - assert!(nan.log(2.3).is_nan()); - assert_eq!(inf.log(10.0), inf); - assert!(neg_inf.log(8.8).is_nan()); - assert!((-2.3f64).log(0.1).is_nan()); - assert_eq!((-0.0f64).log(2.0), neg_inf); - assert_eq!(0.0f64.log(7.0), neg_inf); - } - - #[test] - fn test_log2() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_approx_eq!(10.0f64.log2(), 3.321928); - assert_approx_eq!(2.3f64.log2(), 1.201634); - assert_approx_eq!(1.0f64.exp().log2(), 1.442695); - assert!(nan.log2().is_nan()); - assert_eq!(inf.log2(), inf); - assert!(neg_inf.log2().is_nan()); - assert!((-2.3f64).log2().is_nan()); - assert_eq!((-0.0f64).log2(), neg_inf); - assert_eq!(0.0f64.log2(), neg_inf); - } - - #[test] - fn test_log10() { - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(10.0f64.log10(), 1.0); - assert_approx_eq!(2.3f64.log10(), 0.361728); - assert_approx_eq!(1.0f64.exp().log10(), 0.434294); - assert_eq!(1.0f64.log10(), 0.0); - assert!(nan.log10().is_nan()); - assert_eq!(inf.log10(), inf); - assert!(neg_inf.log10().is_nan()); - assert!((-2.3f64).log10().is_nan()); - assert_eq!((-0.0f64).log10(), neg_inf); - assert_eq!(0.0f64.log10(), neg_inf); - } - - #[test] - fn test_to_degrees() { - let pi: f64 = consts::PI; - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(0.0f64.to_degrees(), 0.0); - assert_approx_eq!((-5.8f64).to_degrees(), -332.315521); - assert_eq!(pi.to_degrees(), 180.0); - assert!(nan.to_degrees().is_nan()); - assert_eq!(inf.to_degrees(), inf); - assert_eq!(neg_inf.to_degrees(), neg_inf); - } - - #[test] - fn test_to_radians() { - let pi: f64 = consts::PI; - let nan: f64 = f64::NAN; - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(0.0f64.to_radians(), 0.0); - assert_approx_eq!(154.6f64.to_radians(), 2.698279); - assert_approx_eq!((-332.31f64).to_radians(), -5.799903); - assert_eq!(180.0f64.to_radians(), pi); - assert!(nan.to_radians().is_nan()); - assert_eq!(inf.to_radians(), inf); - assert_eq!(neg_inf.to_radians(), neg_inf); - } - - #[test] - fn test_asinh() { - assert_eq!(0.0f64.asinh(), 0.0f64); - assert_eq!((-0.0f64).asinh(), -0.0f64); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf.asinh(), inf); - assert_eq!(neg_inf.asinh(), neg_inf); - assert!(nan.asinh().is_nan()); - assert!((-0.0f64).asinh().is_sign_negative()); - // issue 63271 - assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64); - assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64); - // regression test for the catastrophic cancellation fixed in 72486 - assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083); - } - - #[test] - fn test_acosh() { - assert_eq!(1.0f64.acosh(), 0.0f64); - assert!(0.999f64.acosh().is_nan()); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(inf.acosh(), inf); - assert!(neg_inf.acosh().is_nan()); - assert!(nan.acosh().is_nan()); - assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64); - assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64); - } - - #[test] - fn test_atanh() { - assert_eq!(0.0f64.atanh(), 0.0f64); - assert_eq!((-0.0f64).atanh(), -0.0f64); - - let inf: f64 = f64::INFINITY; - let neg_inf: f64 = f64::NEG_INFINITY; - let nan: f64 = f64::NAN; - assert_eq!(1.0f64.atanh(), inf); - assert_eq!((-1.0f64).atanh(), neg_inf); - assert!(2f64.atanh().atanh().is_nan()); - assert!((-2f64).atanh().atanh().is_nan()); - assert!(inf.atanh().is_nan()); - assert!(neg_inf.atanh().is_nan()); - assert!(nan.atanh().is_nan()); - assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); - assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64); - } - - #[test] - fn test_real_consts() { - use super::consts; - let pi: f64 = consts::PI; - let frac_pi_2: f64 = consts::FRAC_PI_2; - let frac_pi_3: f64 = consts::FRAC_PI_3; - let frac_pi_4: f64 = consts::FRAC_PI_4; - let frac_pi_6: f64 = consts::FRAC_PI_6; - let frac_pi_8: f64 = consts::FRAC_PI_8; - let frac_1_pi: f64 = consts::FRAC_1_PI; - let frac_2_pi: f64 = consts::FRAC_2_PI; - let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI; - let sqrt2: f64 = consts::SQRT_2; - let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2; - let e: f64 = consts::E; - let log2_e: f64 = consts::LOG2_E; - let log10_e: f64 = consts::LOG10_E; - let ln_2: f64 = consts::LN_2; - let ln_10: f64 = consts::LN_10; - - assert_approx_eq!(frac_pi_2, pi / 2f64); - assert_approx_eq!(frac_pi_3, pi / 3f64); - assert_approx_eq!(frac_pi_4, pi / 4f64); - assert_approx_eq!(frac_pi_6, pi / 6f64); - assert_approx_eq!(frac_pi_8, pi / 8f64); - assert_approx_eq!(frac_1_pi, 1f64 / pi); - assert_approx_eq!(frac_2_pi, 2f64 / pi); - assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt()); - assert_approx_eq!(sqrt2, 2f64.sqrt()); - assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt()); - assert_approx_eq!(log2_e, e.log2()); - assert_approx_eq!(log10_e, e.log10()); - assert_approx_eq!(ln_2, 2f64.ln()); - assert_approx_eq!(ln_10, 10f64.ln()); - } - - #[test] - fn test_float_bits_conv() { - assert_eq!((1f64).to_bits(), 0x3ff0000000000000); - assert_eq!((12.5f64).to_bits(), 0x4029000000000000); - assert_eq!((1337f64).to_bits(), 0x4094e40000000000); - assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000); - assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0); - assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5); - assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0); - assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25); - - // Check that NaNs roundtrip their bits regardless of signaling-ness - // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits - let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; - let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; - assert!(f64::from_bits(masked_nan1).is_nan()); - assert!(f64::from_bits(masked_nan2).is_nan()); - - assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1); - assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2); - } - - #[test] - #[should_panic] - fn test_clamp_min_greater_than_max() { - let _ = 1.0f64.clamp(3.0, 1.0); - } - - #[test] - #[should_panic] - fn test_clamp_min_is_nan() { - let _ = 1.0f64.clamp(f64::NAN, 1.0); - } - - #[test] - #[should_panic] - fn test_clamp_max_is_nan() { - let _ = 1.0f64.clamp(3.0, f64::NAN); - } - - #[test] - fn test_total_cmp() { - use core::cmp::Ordering; - - fn quiet_bit_mask() -> u64 { - 1 << (f64::MANTISSA_DIGITS - 2) - } - - fn min_subnorm() -> f64 { - f64::MIN_POSITIVE / f64::powf(2.0, f64::MANTISSA_DIGITS as f64 - 1.0) - } - - fn max_subnorm() -> f64 { - f64::MIN_POSITIVE - min_subnorm() - } - - fn q_nan() -> f64 { - f64::from_bits(f64::NAN.to_bits() | quiet_bit_mask()) - } - - fn s_nan() -> f64 { - f64::from_bits((f64::NAN.to_bits() & !quiet_bit_mask()) + 42) - } - - assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan())); - assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan())); - assert_eq!(Ordering::Equal, (-f64::INFINITY).total_cmp(&-f64::INFINITY)); - assert_eq!(Ordering::Equal, (-f64::MAX).total_cmp(&-f64::MAX)); - assert_eq!(Ordering::Equal, (-2.5_f64).total_cmp(&-2.5)); - assert_eq!(Ordering::Equal, (-1.0_f64).total_cmp(&-1.0)); - assert_eq!(Ordering::Equal, (-1.5_f64).total_cmp(&-1.5)); - assert_eq!(Ordering::Equal, (-0.5_f64).total_cmp(&-0.5)); - assert_eq!(Ordering::Equal, (-f64::MIN_POSITIVE).total_cmp(&-f64::MIN_POSITIVE)); - assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Equal, (-0.0_f64).total_cmp(&-0.0)); - assert_eq!(Ordering::Equal, 0.0_f64.total_cmp(&0.0)); - assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm())); - assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm())); - assert_eq!(Ordering::Equal, f64::MIN_POSITIVE.total_cmp(&f64::MIN_POSITIVE)); - assert_eq!(Ordering::Equal, 0.5_f64.total_cmp(&0.5)); - assert_eq!(Ordering::Equal, 1.0_f64.total_cmp(&1.0)); - assert_eq!(Ordering::Equal, 1.5_f64.total_cmp(&1.5)); - assert_eq!(Ordering::Equal, 2.5_f64.total_cmp(&2.5)); - assert_eq!(Ordering::Equal, f64::MAX.total_cmp(&f64::MAX)); - assert_eq!(Ordering::Equal, f64::INFINITY.total_cmp(&f64::INFINITY)); - assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan())); - assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan())); - - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY)); - assert_eq!(Ordering::Less, (-f64::INFINITY).total_cmp(&-f64::MAX)); - assert_eq!(Ordering::Less, (-f64::MAX).total_cmp(&-2.5)); - assert_eq!(Ordering::Less, (-2.5_f64).total_cmp(&-1.5)); - assert_eq!(Ordering::Less, (-1.5_f64).total_cmp(&-1.0)); - assert_eq!(Ordering::Less, (-1.0_f64).total_cmp(&-0.5)); - assert_eq!(Ordering::Less, (-0.5_f64).total_cmp(&-f64::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-f64::MIN_POSITIVE).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0)); - assert_eq!(Ordering::Less, (-0.0_f64).total_cmp(&0.0)); - assert_eq!(Ordering::Less, 0.0_f64.total_cmp(&min_subnorm())); - assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm())); - assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f64::MIN_POSITIVE)); - assert_eq!(Ordering::Less, f64::MIN_POSITIVE.total_cmp(&0.5)); - assert_eq!(Ordering::Less, 0.5_f64.total_cmp(&1.0)); - assert_eq!(Ordering::Less, 1.0_f64.total_cmp(&1.5)); - assert_eq!(Ordering::Less, 1.5_f64.total_cmp(&2.5)); - assert_eq!(Ordering::Less, 2.5_f64.total_cmp(&f64::MAX)); - assert_eq!(Ordering::Less, f64::MAX.total_cmp(&f64::INFINITY)); - assert_eq!(Ordering::Less, f64::INFINITY.total_cmp(&s_nan())); - assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan())); - - assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan())); - assert_eq!(Ordering::Greater, (-f64::INFINITY).total_cmp(&-s_nan())); - assert_eq!(Ordering::Greater, (-f64::MAX).total_cmp(&-f64::INFINITY)); - assert_eq!(Ordering::Greater, (-2.5_f64).total_cmp(&-f64::MAX)); - assert_eq!(Ordering::Greater, (-1.5_f64).total_cmp(&-2.5)); - assert_eq!(Ordering::Greater, (-1.0_f64).total_cmp(&-1.5)); - assert_eq!(Ordering::Greater, (-0.5_f64).total_cmp(&-1.0)); - assert_eq!(Ordering::Greater, (-f64::MIN_POSITIVE).total_cmp(&-0.5)); - assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f64::MIN_POSITIVE)); - assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Greater, (-0.0_f64).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Greater, 0.0_f64.total_cmp(&-0.0)); - assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0)); - assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm())); - assert_eq!(Ordering::Greater, f64::MIN_POSITIVE.total_cmp(&max_subnorm())); - assert_eq!(Ordering::Greater, 0.5_f64.total_cmp(&f64::MIN_POSITIVE)); - assert_eq!(Ordering::Greater, 1.0_f64.total_cmp(&0.5)); - assert_eq!(Ordering::Greater, 1.5_f64.total_cmp(&1.0)); - assert_eq!(Ordering::Greater, 2.5_f64.total_cmp(&1.5)); - assert_eq!(Ordering::Greater, f64::MAX.total_cmp(&2.5)); - assert_eq!(Ordering::Greater, f64::INFINITY.total_cmp(&f64::MAX)); - assert_eq!(Ordering::Greater, s_nan().total_cmp(&f64::INFINITY)); - assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan())); - - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::INFINITY)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MAX)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm())); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MAX)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::INFINITY)); - assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan())); - - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MAX)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm())); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MIN_POSITIVE)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MAX)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY)); - assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan())); - } -} diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs new file mode 100644 index 00000000000..5c163cfe90e --- /dev/null +++ b/library/std/src/f64/tests.rs @@ -0,0 +1,755 @@ +use crate::f64::consts; +use crate::num::FpCategory as Fp; +use crate::num::*; + +#[test] +fn test_num_f64() { + test_num(10f64, 2f64); +} + +#[test] +fn test_min_nan() { + assert_eq!(f64::NAN.min(2.0), 2.0); + assert_eq!(2.0f64.min(f64::NAN), 2.0); +} + +#[test] +fn test_max_nan() { + assert_eq!(f64::NAN.max(2.0), 2.0); + assert_eq!(2.0f64.max(f64::NAN), 2.0); +} + +#[test] +fn test_nan() { + let nan: f64 = f64::NAN; + assert!(nan.is_nan()); + assert!(!nan.is_infinite()); + assert!(!nan.is_finite()); + assert!(!nan.is_normal()); + assert!(nan.is_sign_positive()); + assert!(!nan.is_sign_negative()); + assert_eq!(Fp::Nan, nan.classify()); +} + +#[test] +fn test_infinity() { + let inf: f64 = f64::INFINITY; + assert!(inf.is_infinite()); + assert!(!inf.is_finite()); + assert!(inf.is_sign_positive()); + assert!(!inf.is_sign_negative()); + assert!(!inf.is_nan()); + assert!(!inf.is_normal()); + assert_eq!(Fp::Infinite, inf.classify()); +} + +#[test] +fn test_neg_infinity() { + let neg_inf: f64 = f64::NEG_INFINITY; + assert!(neg_inf.is_infinite()); + assert!(!neg_inf.is_finite()); + assert!(!neg_inf.is_sign_positive()); + assert!(neg_inf.is_sign_negative()); + assert!(!neg_inf.is_nan()); + assert!(!neg_inf.is_normal()); + assert_eq!(Fp::Infinite, neg_inf.classify()); +} + +#[test] +fn test_zero() { + let zero: f64 = 0.0f64; + assert_eq!(0.0, zero); + assert!(!zero.is_infinite()); + assert!(zero.is_finite()); + assert!(zero.is_sign_positive()); + assert!(!zero.is_sign_negative()); + assert!(!zero.is_nan()); + assert!(!zero.is_normal()); + assert_eq!(Fp::Zero, zero.classify()); +} + +#[test] +fn test_neg_zero() { + let neg_zero: f64 = -0.0; + assert_eq!(0.0, neg_zero); + assert!(!neg_zero.is_infinite()); + assert!(neg_zero.is_finite()); + assert!(!neg_zero.is_sign_positive()); + assert!(neg_zero.is_sign_negative()); + assert!(!neg_zero.is_nan()); + assert!(!neg_zero.is_normal()); + assert_eq!(Fp::Zero, neg_zero.classify()); +} + +#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 +#[test] +fn test_one() { + let one: f64 = 1.0f64; + assert_eq!(1.0, one); + assert!(!one.is_infinite()); + assert!(one.is_finite()); + assert!(one.is_sign_positive()); + assert!(!one.is_sign_negative()); + assert!(!one.is_nan()); + assert!(one.is_normal()); + assert_eq!(Fp::Normal, one.classify()); +} + +#[test] +fn test_is_nan() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert!(nan.is_nan()); + assert!(!0.0f64.is_nan()); + assert!(!5.3f64.is_nan()); + assert!(!(-10.732f64).is_nan()); + assert!(!inf.is_nan()); + assert!(!neg_inf.is_nan()); +} + +#[test] +fn test_is_infinite() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert!(!nan.is_infinite()); + assert!(inf.is_infinite()); + assert!(neg_inf.is_infinite()); + assert!(!0.0f64.is_infinite()); + assert!(!42.8f64.is_infinite()); + assert!(!(-109.2f64).is_infinite()); +} + +#[test] +fn test_is_finite() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert!(!nan.is_finite()); + assert!(!inf.is_finite()); + assert!(!neg_inf.is_finite()); + assert!(0.0f64.is_finite()); + assert!(42.8f64.is_finite()); + assert!((-109.2f64).is_finite()); +} + +#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 +#[test] +fn test_is_normal() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let zero: f64 = 0.0f64; + let neg_zero: f64 = -0.0; + assert!(!nan.is_normal()); + assert!(!inf.is_normal()); + assert!(!neg_inf.is_normal()); + assert!(!zero.is_normal()); + assert!(!neg_zero.is_normal()); + assert!(1f64.is_normal()); + assert!(1e-307f64.is_normal()); + assert!(!1e-308f64.is_normal()); +} + +#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630 +#[test] +fn test_classify() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let zero: f64 = 0.0f64; + let neg_zero: f64 = -0.0; + assert_eq!(nan.classify(), Fp::Nan); + assert_eq!(inf.classify(), Fp::Infinite); + assert_eq!(neg_inf.classify(), Fp::Infinite); + assert_eq!(zero.classify(), Fp::Zero); + assert_eq!(neg_zero.classify(), Fp::Zero); + assert_eq!(1e-307f64.classify(), Fp::Normal); + assert_eq!(1e-308f64.classify(), Fp::Subnormal); +} + +#[test] +fn test_floor() { + assert_approx_eq!(1.0f64.floor(), 1.0f64); + assert_approx_eq!(1.3f64.floor(), 1.0f64); + assert_approx_eq!(1.5f64.floor(), 1.0f64); + assert_approx_eq!(1.7f64.floor(), 1.0f64); + assert_approx_eq!(0.0f64.floor(), 0.0f64); + assert_approx_eq!((-0.0f64).floor(), -0.0f64); + assert_approx_eq!((-1.0f64).floor(), -1.0f64); + assert_approx_eq!((-1.3f64).floor(), -2.0f64); + assert_approx_eq!((-1.5f64).floor(), -2.0f64); + assert_approx_eq!((-1.7f64).floor(), -2.0f64); +} + +#[test] +fn test_ceil() { + assert_approx_eq!(1.0f64.ceil(), 1.0f64); + assert_approx_eq!(1.3f64.ceil(), 2.0f64); + assert_approx_eq!(1.5f64.ceil(), 2.0f64); + assert_approx_eq!(1.7f64.ceil(), 2.0f64); + assert_approx_eq!(0.0f64.ceil(), 0.0f64); + assert_approx_eq!((-0.0f64).ceil(), -0.0f64); + assert_approx_eq!((-1.0f64).ceil(), -1.0f64); + assert_approx_eq!((-1.3f64).ceil(), -1.0f64); + assert_approx_eq!((-1.5f64).ceil(), -1.0f64); + assert_approx_eq!((-1.7f64).ceil(), -1.0f64); +} + +#[test] +fn test_round() { + assert_approx_eq!(1.0f64.round(), 1.0f64); + assert_approx_eq!(1.3f64.round(), 1.0f64); + assert_approx_eq!(1.5f64.round(), 2.0f64); + assert_approx_eq!(1.7f64.round(), 2.0f64); + assert_approx_eq!(0.0f64.round(), 0.0f64); + assert_approx_eq!((-0.0f64).round(), -0.0f64); + assert_approx_eq!((-1.0f64).round(), -1.0f64); + assert_approx_eq!((-1.3f64).round(), -1.0f64); + assert_approx_eq!((-1.5f64).round(), -2.0f64); + assert_approx_eq!((-1.7f64).round(), -2.0f64); +} + +#[test] +fn test_trunc() { + assert_approx_eq!(1.0f64.trunc(), 1.0f64); + assert_approx_eq!(1.3f64.trunc(), 1.0f64); + assert_approx_eq!(1.5f64.trunc(), 1.0f64); + assert_approx_eq!(1.7f64.trunc(), 1.0f64); + assert_approx_eq!(0.0f64.trunc(), 0.0f64); + assert_approx_eq!((-0.0f64).trunc(), -0.0f64); + assert_approx_eq!((-1.0f64).trunc(), -1.0f64); + assert_approx_eq!((-1.3f64).trunc(), -1.0f64); + assert_approx_eq!((-1.5f64).trunc(), -1.0f64); + assert_approx_eq!((-1.7f64).trunc(), -1.0f64); +} + +#[test] +fn test_fract() { + assert_approx_eq!(1.0f64.fract(), 0.0f64); + assert_approx_eq!(1.3f64.fract(), 0.3f64); + assert_approx_eq!(1.5f64.fract(), 0.5f64); + assert_approx_eq!(1.7f64.fract(), 0.7f64); + assert_approx_eq!(0.0f64.fract(), 0.0f64); + assert_approx_eq!((-0.0f64).fract(), -0.0f64); + assert_approx_eq!((-1.0f64).fract(), -0.0f64); + assert_approx_eq!((-1.3f64).fract(), -0.3f64); + assert_approx_eq!((-1.5f64).fract(), -0.5f64); + assert_approx_eq!((-1.7f64).fract(), -0.7f64); +} + +#[test] +fn test_abs() { + assert_eq!(f64::INFINITY.abs(), f64::INFINITY); + assert_eq!(1f64.abs(), 1f64); + assert_eq!(0f64.abs(), 0f64); + assert_eq!((-0f64).abs(), 0f64); + assert_eq!((-1f64).abs(), 1f64); + assert_eq!(f64::NEG_INFINITY.abs(), f64::INFINITY); + assert_eq!((1f64 / f64::NEG_INFINITY).abs(), 0f64); + assert!(f64::NAN.abs().is_nan()); +} + +#[test] +fn test_signum() { + assert_eq!(f64::INFINITY.signum(), 1f64); + assert_eq!(1f64.signum(), 1f64); + assert_eq!(0f64.signum(), 1f64); + assert_eq!((-0f64).signum(), -1f64); + assert_eq!((-1f64).signum(), -1f64); + assert_eq!(f64::NEG_INFINITY.signum(), -1f64); + assert_eq!((1f64 / f64::NEG_INFINITY).signum(), -1f64); + assert!(f64::NAN.signum().is_nan()); +} + +#[test] +fn test_is_sign_positive() { + assert!(f64::INFINITY.is_sign_positive()); + assert!(1f64.is_sign_positive()); + assert!(0f64.is_sign_positive()); + assert!(!(-0f64).is_sign_positive()); + assert!(!(-1f64).is_sign_positive()); + assert!(!f64::NEG_INFINITY.is_sign_positive()); + assert!(!(1f64 / f64::NEG_INFINITY).is_sign_positive()); + assert!(f64::NAN.is_sign_positive()); + assert!(!(-f64::NAN).is_sign_positive()); +} + +#[test] +fn test_is_sign_negative() { + assert!(!f64::INFINITY.is_sign_negative()); + assert!(!1f64.is_sign_negative()); + assert!(!0f64.is_sign_negative()); + assert!((-0f64).is_sign_negative()); + assert!((-1f64).is_sign_negative()); + assert!(f64::NEG_INFINITY.is_sign_negative()); + assert!((1f64 / f64::NEG_INFINITY).is_sign_negative()); + assert!(!f64::NAN.is_sign_negative()); + assert!((-f64::NAN).is_sign_negative()); +} + +#[test] +fn test_mul_add() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05); + assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65); + assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2); + assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6); + assert!(nan.mul_add(7.8, 9.0).is_nan()); + assert_eq!(inf.mul_add(7.8, 9.0), inf); + assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf); + assert_eq!(8.9f64.mul_add(inf, 3.2), inf); + assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf); +} + +#[test] +fn test_recip() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(1.0f64.recip(), 1.0); + assert_eq!(2.0f64.recip(), 0.5); + assert_eq!((-0.4f64).recip(), -2.5); + assert_eq!(0.0f64.recip(), inf); + assert!(nan.recip().is_nan()); + assert_eq!(inf.recip(), 0.0); + assert_eq!(neg_inf.recip(), 0.0); +} + +#[test] +fn test_powi() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(1.0f64.powi(1), 1.0); + assert_approx_eq!((-3.1f64).powi(2), 9.61); + assert_approx_eq!(5.9f64.powi(-2), 0.028727); + assert_eq!(8.3f64.powi(0), 1.0); + assert!(nan.powi(2).is_nan()); + assert_eq!(inf.powi(3), inf); + assert_eq!(neg_inf.powi(2), inf); +} + +#[test] +fn test_powf() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(1.0f64.powf(1.0), 1.0); + assert_approx_eq!(3.4f64.powf(4.5), 246.408183); + assert_approx_eq!(2.7f64.powf(-3.2), 0.041652); + assert_approx_eq!((-3.1f64).powf(2.0), 9.61); + assert_approx_eq!(5.9f64.powf(-2.0), 0.028727); + assert_eq!(8.3f64.powf(0.0), 1.0); + assert!(nan.powf(2.0).is_nan()); + assert_eq!(inf.powf(2.0), inf); + assert_eq!(neg_inf.powf(3.0), neg_inf); +} + +#[test] +fn test_sqrt_domain() { + assert!(f64::NAN.sqrt().is_nan()); + assert!(f64::NEG_INFINITY.sqrt().is_nan()); + assert!((-1.0f64).sqrt().is_nan()); + assert_eq!((-0.0f64).sqrt(), -0.0); + assert_eq!(0.0f64.sqrt(), 0.0); + assert_eq!(1.0f64.sqrt(), 1.0); + assert_eq!(f64::INFINITY.sqrt(), f64::INFINITY); +} + +#[test] +fn test_exp() { + assert_eq!(1.0, 0.0f64.exp()); + assert_approx_eq!(2.718282, 1.0f64.exp()); + assert_approx_eq!(148.413159, 5.0f64.exp()); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; + assert_eq!(inf, inf.exp()); + assert_eq!(0.0, neg_inf.exp()); + assert!(nan.exp().is_nan()); +} + +#[test] +fn test_exp2() { + assert_eq!(32.0, 5.0f64.exp2()); + assert_eq!(1.0, 0.0f64.exp2()); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; + assert_eq!(inf, inf.exp2()); + assert_eq!(0.0, neg_inf.exp2()); + assert!(nan.exp2().is_nan()); +} + +#[test] +fn test_ln() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_approx_eq!(1.0f64.exp().ln(), 1.0); + assert!(nan.ln().is_nan()); + assert_eq!(inf.ln(), inf); + assert!(neg_inf.ln().is_nan()); + assert!((-2.3f64).ln().is_nan()); + assert_eq!((-0.0f64).ln(), neg_inf); + assert_eq!(0.0f64.ln(), neg_inf); + assert_approx_eq!(4.0f64.ln(), 1.386294); +} + +#[test] +fn test_log() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(10.0f64.log(10.0), 1.0); + assert_approx_eq!(2.3f64.log(3.5), 0.664858); + assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0); + assert!(1.0f64.log(1.0).is_nan()); + assert!(1.0f64.log(-13.9).is_nan()); + assert!(nan.log(2.3).is_nan()); + assert_eq!(inf.log(10.0), inf); + assert!(neg_inf.log(8.8).is_nan()); + assert!((-2.3f64).log(0.1).is_nan()); + assert_eq!((-0.0f64).log(2.0), neg_inf); + assert_eq!(0.0f64.log(7.0), neg_inf); +} + +#[test] +fn test_log2() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_approx_eq!(10.0f64.log2(), 3.321928); + assert_approx_eq!(2.3f64.log2(), 1.201634); + assert_approx_eq!(1.0f64.exp().log2(), 1.442695); + assert!(nan.log2().is_nan()); + assert_eq!(inf.log2(), inf); + assert!(neg_inf.log2().is_nan()); + assert!((-2.3f64).log2().is_nan()); + assert_eq!((-0.0f64).log2(), neg_inf); + assert_eq!(0.0f64.log2(), neg_inf); +} + +#[test] +fn test_log10() { + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(10.0f64.log10(), 1.0); + assert_approx_eq!(2.3f64.log10(), 0.361728); + assert_approx_eq!(1.0f64.exp().log10(), 0.434294); + assert_eq!(1.0f64.log10(), 0.0); + assert!(nan.log10().is_nan()); + assert_eq!(inf.log10(), inf); + assert!(neg_inf.log10().is_nan()); + assert!((-2.3f64).log10().is_nan()); + assert_eq!((-0.0f64).log10(), neg_inf); + assert_eq!(0.0f64.log10(), neg_inf); +} + +#[test] +fn test_to_degrees() { + let pi: f64 = consts::PI; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(0.0f64.to_degrees(), 0.0); + assert_approx_eq!((-5.8f64).to_degrees(), -332.315521); + assert_eq!(pi.to_degrees(), 180.0); + assert!(nan.to_degrees().is_nan()); + assert_eq!(inf.to_degrees(), inf); + assert_eq!(neg_inf.to_degrees(), neg_inf); +} + +#[test] +fn test_to_radians() { + let pi: f64 = consts::PI; + let nan: f64 = f64::NAN; + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + assert_eq!(0.0f64.to_radians(), 0.0); + assert_approx_eq!(154.6f64.to_radians(), 2.698279); + assert_approx_eq!((-332.31f64).to_radians(), -5.799903); + assert_eq!(180.0f64.to_radians(), pi); + assert!(nan.to_radians().is_nan()); + assert_eq!(inf.to_radians(), inf); + assert_eq!(neg_inf.to_radians(), neg_inf); +} + +#[test] +fn test_asinh() { + assert_eq!(0.0f64.asinh(), 0.0f64); + assert_eq!((-0.0f64).asinh(), -0.0f64); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; + assert_eq!(inf.asinh(), inf); + assert_eq!(neg_inf.asinh(), neg_inf); + assert!(nan.asinh().is_nan()); + assert!((-0.0f64).asinh().is_sign_negative()); + // issue 63271 + assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64); + assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64); + // regression test for the catastrophic cancellation fixed in 72486 + assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083); +} + +#[test] +fn test_acosh() { + assert_eq!(1.0f64.acosh(), 0.0f64); + assert!(0.999f64.acosh().is_nan()); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; + assert_eq!(inf.acosh(), inf); + assert!(neg_inf.acosh().is_nan()); + assert!(nan.acosh().is_nan()); + assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64); + assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64); +} + +#[test] +fn test_atanh() { + assert_eq!(0.0f64.atanh(), 0.0f64); + assert_eq!((-0.0f64).atanh(), -0.0f64); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = f64::NEG_INFINITY; + let nan: f64 = f64::NAN; + assert_eq!(1.0f64.atanh(), inf); + assert_eq!((-1.0f64).atanh(), neg_inf); + assert!(2f64.atanh().atanh().is_nan()); + assert!((-2f64).atanh().atanh().is_nan()); + assert!(inf.atanh().is_nan()); + assert!(neg_inf.atanh().is_nan()); + assert!(nan.atanh().is_nan()); + assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); + assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64); +} + +#[test] +fn test_real_consts() { + use super::consts; + let pi: f64 = consts::PI; + let frac_pi_2: f64 = consts::FRAC_PI_2; + let frac_pi_3: f64 = consts::FRAC_PI_3; + let frac_pi_4: f64 = consts::FRAC_PI_4; + let frac_pi_6: f64 = consts::FRAC_PI_6; + let frac_pi_8: f64 = consts::FRAC_PI_8; + let frac_1_pi: f64 = consts::FRAC_1_PI; + let frac_2_pi: f64 = consts::FRAC_2_PI; + let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI; + let sqrt2: f64 = consts::SQRT_2; + let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2; + let e: f64 = consts::E; + let log2_e: f64 = consts::LOG2_E; + let log10_e: f64 = consts::LOG10_E; + let ln_2: f64 = consts::LN_2; + let ln_10: f64 = consts::LN_10; + + assert_approx_eq!(frac_pi_2, pi / 2f64); + assert_approx_eq!(frac_pi_3, pi / 3f64); + assert_approx_eq!(frac_pi_4, pi / 4f64); + assert_approx_eq!(frac_pi_6, pi / 6f64); + assert_approx_eq!(frac_pi_8, pi / 8f64); + assert_approx_eq!(frac_1_pi, 1f64 / pi); + assert_approx_eq!(frac_2_pi, 2f64 / pi); + assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt()); + assert_approx_eq!(sqrt2, 2f64.sqrt()); + assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt()); + assert_approx_eq!(log2_e, e.log2()); + assert_approx_eq!(log10_e, e.log10()); + assert_approx_eq!(ln_2, 2f64.ln()); + assert_approx_eq!(ln_10, 10f64.ln()); +} + +#[test] +fn test_float_bits_conv() { + assert_eq!((1f64).to_bits(), 0x3ff0000000000000); + assert_eq!((12.5f64).to_bits(), 0x4029000000000000); + assert_eq!((1337f64).to_bits(), 0x4094e40000000000); + assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000); + assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0); + assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5); + assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0); + assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signaling-ness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; + let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; + assert!(f64::from_bits(masked_nan1).is_nan()); + assert!(f64::from_bits(masked_nan2).is_nan()); + + assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1); + assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2); +} + +#[test] +#[should_panic] +fn test_clamp_min_greater_than_max() { + let _ = 1.0f64.clamp(3.0, 1.0); +} + +#[test] +#[should_panic] +fn test_clamp_min_is_nan() { + let _ = 1.0f64.clamp(f64::NAN, 1.0); +} + +#[test] +#[should_panic] +fn test_clamp_max_is_nan() { + let _ = 1.0f64.clamp(3.0, f64::NAN); +} + +#[test] +fn test_total_cmp() { + use core::cmp::Ordering; + + fn quiet_bit_mask() -> u64 { + 1 << (f64::MANTISSA_DIGITS - 2) + } + + fn min_subnorm() -> f64 { + f64::MIN_POSITIVE / f64::powf(2.0, f64::MANTISSA_DIGITS as f64 - 1.0) + } + + fn max_subnorm() -> f64 { + f64::MIN_POSITIVE - min_subnorm() + } + + fn q_nan() -> f64 { + f64::from_bits(f64::NAN.to_bits() | quiet_bit_mask()) + } + + fn s_nan() -> f64 { + f64::from_bits((f64::NAN.to_bits() & !quiet_bit_mask()) + 42) + } + + assert_eq!(Ordering::Equal, (-q_nan()).total_cmp(&-q_nan())); + assert_eq!(Ordering::Equal, (-s_nan()).total_cmp(&-s_nan())); + assert_eq!(Ordering::Equal, (-f64::INFINITY).total_cmp(&-f64::INFINITY)); + assert_eq!(Ordering::Equal, (-f64::MAX).total_cmp(&-f64::MAX)); + assert_eq!(Ordering::Equal, (-2.5_f64).total_cmp(&-2.5)); + assert_eq!(Ordering::Equal, (-1.0_f64).total_cmp(&-1.0)); + assert_eq!(Ordering::Equal, (-1.5_f64).total_cmp(&-1.5)); + assert_eq!(Ordering::Equal, (-0.5_f64).total_cmp(&-0.5)); + assert_eq!(Ordering::Equal, (-f64::MIN_POSITIVE).total_cmp(&-f64::MIN_POSITIVE)); + assert_eq!(Ordering::Equal, (-max_subnorm()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Equal, (-min_subnorm()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Equal, (-0.0_f64).total_cmp(&-0.0)); + assert_eq!(Ordering::Equal, 0.0_f64.total_cmp(&0.0)); + assert_eq!(Ordering::Equal, min_subnorm().total_cmp(&min_subnorm())); + assert_eq!(Ordering::Equal, max_subnorm().total_cmp(&max_subnorm())); + assert_eq!(Ordering::Equal, f64::MIN_POSITIVE.total_cmp(&f64::MIN_POSITIVE)); + assert_eq!(Ordering::Equal, 0.5_f64.total_cmp(&0.5)); + assert_eq!(Ordering::Equal, 1.0_f64.total_cmp(&1.0)); + assert_eq!(Ordering::Equal, 1.5_f64.total_cmp(&1.5)); + assert_eq!(Ordering::Equal, 2.5_f64.total_cmp(&2.5)); + assert_eq!(Ordering::Equal, f64::MAX.total_cmp(&f64::MAX)); + assert_eq!(Ordering::Equal, f64::INFINITY.total_cmp(&f64::INFINITY)); + assert_eq!(Ordering::Equal, s_nan().total_cmp(&s_nan())); + assert_eq!(Ordering::Equal, q_nan().total_cmp(&q_nan())); + + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY)); + assert_eq!(Ordering::Less, (-f64::INFINITY).total_cmp(&-f64::MAX)); + assert_eq!(Ordering::Less, (-f64::MAX).total_cmp(&-2.5)); + assert_eq!(Ordering::Less, (-2.5_f64).total_cmp(&-1.5)); + assert_eq!(Ordering::Less, (-1.5_f64).total_cmp(&-1.0)); + assert_eq!(Ordering::Less, (-1.0_f64).total_cmp(&-0.5)); + assert_eq!(Ordering::Less, (-0.5_f64).total_cmp(&-f64::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-f64::MIN_POSITIVE).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-max_subnorm()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-min_subnorm()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-0.0_f64).total_cmp(&0.0)); + assert_eq!(Ordering::Less, 0.0_f64.total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, min_subnorm().total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, max_subnorm().total_cmp(&f64::MIN_POSITIVE)); + assert_eq!(Ordering::Less, f64::MIN_POSITIVE.total_cmp(&0.5)); + assert_eq!(Ordering::Less, 0.5_f64.total_cmp(&1.0)); + assert_eq!(Ordering::Less, 1.0_f64.total_cmp(&1.5)); + assert_eq!(Ordering::Less, 1.5_f64.total_cmp(&2.5)); + assert_eq!(Ordering::Less, 2.5_f64.total_cmp(&f64::MAX)); + assert_eq!(Ordering::Less, f64::MAX.total_cmp(&f64::INFINITY)); + assert_eq!(Ordering::Less, f64::INFINITY.total_cmp(&s_nan())); + assert_eq!(Ordering::Less, s_nan().total_cmp(&q_nan())); + + assert_eq!(Ordering::Greater, (-s_nan()).total_cmp(&-q_nan())); + assert_eq!(Ordering::Greater, (-f64::INFINITY).total_cmp(&-s_nan())); + assert_eq!(Ordering::Greater, (-f64::MAX).total_cmp(&-f64::INFINITY)); + assert_eq!(Ordering::Greater, (-2.5_f64).total_cmp(&-f64::MAX)); + assert_eq!(Ordering::Greater, (-1.5_f64).total_cmp(&-2.5)); + assert_eq!(Ordering::Greater, (-1.0_f64).total_cmp(&-1.5)); + assert_eq!(Ordering::Greater, (-0.5_f64).total_cmp(&-1.0)); + assert_eq!(Ordering::Greater, (-f64::MIN_POSITIVE).total_cmp(&-0.5)); + assert_eq!(Ordering::Greater, (-max_subnorm()).total_cmp(&-f64::MIN_POSITIVE)); + assert_eq!(Ordering::Greater, (-min_subnorm()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Greater, (-0.0_f64).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Greater, 0.0_f64.total_cmp(&-0.0)); + assert_eq!(Ordering::Greater, min_subnorm().total_cmp(&0.0)); + assert_eq!(Ordering::Greater, max_subnorm().total_cmp(&min_subnorm())); + assert_eq!(Ordering::Greater, f64::MIN_POSITIVE.total_cmp(&max_subnorm())); + assert_eq!(Ordering::Greater, 0.5_f64.total_cmp(&f64::MIN_POSITIVE)); + assert_eq!(Ordering::Greater, 1.0_f64.total_cmp(&0.5)); + assert_eq!(Ordering::Greater, 1.5_f64.total_cmp(&1.0)); + assert_eq!(Ordering::Greater, 2.5_f64.total_cmp(&1.5)); + assert_eq!(Ordering::Greater, f64::MAX.total_cmp(&2.5)); + assert_eq!(Ordering::Greater, f64::INFINITY.total_cmp(&f64::MAX)); + assert_eq!(Ordering::Greater, s_nan().total_cmp(&f64::INFINITY)); + assert_eq!(Ordering::Greater, q_nan().total_cmp(&s_nan())); + + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-s_nan())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::INFINITY)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MAX)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-2.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-1.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-f64::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&0.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.0)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&1.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&2.5)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::MAX)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&f64::INFINITY)); + assert_eq!(Ordering::Less, (-q_nan()).total_cmp(&s_nan())); + + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::INFINITY)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MAX)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-2.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-1.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-f64::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-max_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-min_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&-0.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&min_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&max_subnorm())); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MIN_POSITIVE)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&0.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.0)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&1.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&2.5)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::MAX)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY)); + assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan())); +} diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 717967fb768..51deb217c7c 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -1,4 +1,8 @@ #![deny(unsafe_op_in_unsafe_fn)] + +#[cfg(test)] +mod tests; + use crate::ascii; use crate::borrow::{Borrow, Cow}; use crate::cmp::Ordering; @@ -1522,202 +1526,3 @@ impl AsRef<CStr> for CString { self } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::borrow::Cow::{Borrowed, Owned}; - use crate::collections::hash_map::DefaultHasher; - use crate::hash::{Hash, Hasher}; - use crate::os::raw::c_char; - use crate::rc::Rc; - use crate::sync::Arc; - - #[test] - fn c_to_rust() { - let data = b"123\0"; - let ptr = data.as_ptr() as *const c_char; - unsafe { - assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123"); - assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0"); - } - } - - #[test] - fn simple() { - let s = CString::new("1234").unwrap(); - assert_eq!(s.as_bytes(), b"1234"); - assert_eq!(s.as_bytes_with_nul(), b"1234\0"); - } - - #[test] - fn build_with_zero1() { - assert!(CString::new(&b"\0"[..]).is_err()); - } - #[test] - fn build_with_zero2() { - assert!(CString::new(vec![0]).is_err()); - } - - #[test] - fn build_with_zero3() { - unsafe { - let s = CString::from_vec_unchecked(vec![0]); - assert_eq!(s.as_bytes(), b"\0"); - } - } - - #[test] - fn formatted() { - let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap(); - assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#); - } - - #[test] - fn borrowed() { - unsafe { - let s = CStr::from_ptr(b"12\0".as_ptr() as *const _); - assert_eq!(s.to_bytes(), b"12"); - assert_eq!(s.to_bytes_with_nul(), b"12\0"); - } - } - - #[test] - fn to_str() { - let data = b"123\xE2\x80\xA6\0"; - let ptr = data.as_ptr() as *const c_char; - unsafe { - assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…")); - assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…")); - } - let data = b"123\xE2\0"; - let ptr = data.as_ptr() as *const c_char; - unsafe { - assert!(CStr::from_ptr(ptr).to_str().is_err()); - assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}"))); - } - } - - #[test] - fn to_owned() { - let data = b"123\0"; - let ptr = data.as_ptr() as *const c_char; - - let owned = unsafe { CStr::from_ptr(ptr).to_owned() }; - assert_eq!(owned.as_bytes_with_nul(), data); - } - - #[test] - fn equal_hash() { - let data = b"123\xE2\xFA\xA6\0"; - let ptr = data.as_ptr() as *const c_char; - let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) }; - - let mut s = DefaultHasher::new(); - cstr.hash(&mut s); - let cstr_hash = s.finish(); - let mut s = DefaultHasher::new(); - CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s); - let cstring_hash = s.finish(); - - assert_eq!(cstr_hash, cstring_hash); - } - - #[test] - fn from_bytes_with_nul() { - let data = b"123\0"; - let cstr = CStr::from_bytes_with_nul(data); - assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..])); - let cstr = CStr::from_bytes_with_nul(data); - assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..])); - - unsafe { - let cstr = CStr::from_bytes_with_nul(data); - let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data); - assert_eq!(cstr, Ok(cstr_unchecked)); - } - } - - #[test] - fn from_bytes_with_nul_unterminated() { - let data = b"123"; - let cstr = CStr::from_bytes_with_nul(data); - assert!(cstr.is_err()); - } - - #[test] - fn from_bytes_with_nul_interior() { - let data = b"1\023\0"; - let cstr = CStr::from_bytes_with_nul(data); - assert!(cstr.is_err()); - } - - #[test] - fn into_boxed() { - let orig: &[u8] = b"Hello, world!\0"; - let cstr = CStr::from_bytes_with_nul(orig).unwrap(); - let boxed: Box<CStr> = Box::from(cstr); - let cstring = cstr.to_owned().into_boxed_c_str().into_c_string(); - assert_eq!(cstr, &*boxed); - assert_eq!(&*boxed, &*cstring); - assert_eq!(&*cstring, cstr); - } - - #[test] - fn boxed_default() { - let boxed = <Box<CStr>>::default(); - assert_eq!(boxed.to_bytes_with_nul(), &[0]); - } - - #[test] - fn test_c_str_clone_into() { - let mut c_string = CString::new("lorem").unwrap(); - let c_ptr = c_string.as_ptr(); - let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap(); - c_str.clone_into(&mut c_string); - assert_eq!(c_str, c_string.as_c_str()); - // The exact same size shouldn't have needed to move its allocation - assert_eq!(c_ptr, c_string.as_ptr()); - } - - #[test] - fn into_rc() { - let orig: &[u8] = b"Hello, world!\0"; - let cstr = CStr::from_bytes_with_nul(orig).unwrap(); - let rc: Rc<CStr> = Rc::from(cstr); - let arc: Arc<CStr> = Arc::from(cstr); - - assert_eq!(&*rc, cstr); - assert_eq!(&*arc, cstr); - - let rc2: Rc<CStr> = Rc::from(cstr.to_owned()); - let arc2: Arc<CStr> = Arc::from(cstr.to_owned()); - - assert_eq!(&*rc2, cstr); - assert_eq!(&*arc2, cstr); - } - - #[test] - fn cstr_const_constructor() { - const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") }; - - assert_eq!(CSTR.to_str().unwrap(), "Hello, world!"); - } - - #[test] - fn cstr_index_from() { - let original = b"Hello, world!\0"; - let cstr = CStr::from_bytes_with_nul(original).unwrap(); - let result = CStr::from_bytes_with_nul(&original[7..]).unwrap(); - - assert_eq!(&cstr[7..], result); - } - - #[test] - #[should_panic] - fn cstr_index_from_empty() { - let original = b"Hello, world!\0"; - let cstr = CStr::from_bytes_with_nul(original).unwrap(); - let _ = &cstr[original.len()..]; - } -} diff --git a/library/std/src/ffi/c_str/tests.rs b/library/std/src/ffi/c_str/tests.rs new file mode 100644 index 00000000000..4dff3df63a8 --- /dev/null +++ b/library/std/src/ffi/c_str/tests.rs @@ -0,0 +1,195 @@ +use super::*; +use crate::borrow::Cow::{Borrowed, Owned}; +use crate::collections::hash_map::DefaultHasher; +use crate::hash::{Hash, Hasher}; +use crate::os::raw::c_char; +use crate::rc::Rc; +use crate::sync::Arc; + +#[test] +fn c_to_rust() { + let data = b"123\0"; + let ptr = data.as_ptr() as *const c_char; + unsafe { + assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123"); + assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0"); + } +} + +#[test] +fn simple() { + let s = CString::new("1234").unwrap(); + assert_eq!(s.as_bytes(), b"1234"); + assert_eq!(s.as_bytes_with_nul(), b"1234\0"); +} + +#[test] +fn build_with_zero1() { + assert!(CString::new(&b"\0"[..]).is_err()); +} +#[test] +fn build_with_zero2() { + assert!(CString::new(vec![0]).is_err()); +} + +#[test] +fn build_with_zero3() { + unsafe { + let s = CString::from_vec_unchecked(vec![0]); + assert_eq!(s.as_bytes(), b"\0"); + } +} + +#[test] +fn formatted() { + let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap(); + assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#); +} + +#[test] +fn borrowed() { + unsafe { + let s = CStr::from_ptr(b"12\0".as_ptr() as *const _); + assert_eq!(s.to_bytes(), b"12"); + assert_eq!(s.to_bytes_with_nul(), b"12\0"); + } +} + +#[test] +fn to_str() { + let data = b"123\xE2\x80\xA6\0"; + let ptr = data.as_ptr() as *const c_char; + unsafe { + assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…")); + assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…")); + } + let data = b"123\xE2\0"; + let ptr = data.as_ptr() as *const c_char; + unsafe { + assert!(CStr::from_ptr(ptr).to_str().is_err()); + assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}"))); + } +} + +#[test] +fn to_owned() { + let data = b"123\0"; + let ptr = data.as_ptr() as *const c_char; + + let owned = unsafe { CStr::from_ptr(ptr).to_owned() }; + assert_eq!(owned.as_bytes_with_nul(), data); +} + +#[test] +fn equal_hash() { + let data = b"123\xE2\xFA\xA6\0"; + let ptr = data.as_ptr() as *const c_char; + let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) }; + + let mut s = DefaultHasher::new(); + cstr.hash(&mut s); + let cstr_hash = s.finish(); + let mut s = DefaultHasher::new(); + CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s); + let cstring_hash = s.finish(); + + assert_eq!(cstr_hash, cstring_hash); +} + +#[test] +fn from_bytes_with_nul() { + let data = b"123\0"; + let cstr = CStr::from_bytes_with_nul(data); + assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..])); + let cstr = CStr::from_bytes_with_nul(data); + assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..])); + + unsafe { + let cstr = CStr::from_bytes_with_nul(data); + let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data); + assert_eq!(cstr, Ok(cstr_unchecked)); + } +} + +#[test] +fn from_bytes_with_nul_unterminated() { + let data = b"123"; + let cstr = CStr::from_bytes_with_nul(data); + assert!(cstr.is_err()); +} + +#[test] +fn from_bytes_with_nul_interior() { + let data = b"1\023\0"; + let cstr = CStr::from_bytes_with_nul(data); + assert!(cstr.is_err()); +} + +#[test] +fn into_boxed() { + let orig: &[u8] = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(orig).unwrap(); + let boxed: Box<CStr> = Box::from(cstr); + let cstring = cstr.to_owned().into_boxed_c_str().into_c_string(); + assert_eq!(cstr, &*boxed); + assert_eq!(&*boxed, &*cstring); + assert_eq!(&*cstring, cstr); +} + +#[test] +fn boxed_default() { + let boxed = <Box<CStr>>::default(); + assert_eq!(boxed.to_bytes_with_nul(), &[0]); +} + +#[test] +fn test_c_str_clone_into() { + let mut c_string = CString::new("lorem").unwrap(); + let c_ptr = c_string.as_ptr(); + let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap(); + c_str.clone_into(&mut c_string); + assert_eq!(c_str, c_string.as_c_str()); + // The exact same size shouldn't have needed to move its allocation + assert_eq!(c_ptr, c_string.as_ptr()); +} + +#[test] +fn into_rc() { + let orig: &[u8] = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(orig).unwrap(); + let rc: Rc<CStr> = Rc::from(cstr); + let arc: Arc<CStr> = Arc::from(cstr); + + assert_eq!(&*rc, cstr); + assert_eq!(&*arc, cstr); + + let rc2: Rc<CStr> = Rc::from(cstr.to_owned()); + let arc2: Arc<CStr> = Arc::from(cstr.to_owned()); + + assert_eq!(&*rc2, cstr); + assert_eq!(&*arc2, cstr); +} + +#[test] +fn cstr_const_constructor() { + const CSTR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") }; + + assert_eq!(CSTR.to_str().unwrap(), "Hello, world!"); +} + +#[test] +fn cstr_index_from() { + let original = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(original).unwrap(); + let result = CStr::from_bytes_with_nul(&original[7..]).unwrap(); + + assert_eq!(&cstr[7..], result); +} + +#[test] +#[should_panic] +fn cstr_index_from_empty() { + let original = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(original).unwrap(); + let _ = &cstr[original.len()..]; +} diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 262d39d98ee..e0be6d1c836 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::borrow::{Borrow, Cow}; use crate::cmp; use crate::fmt; @@ -1145,172 +1148,3 @@ impl FromStr for OsString { Ok(OsString::from(s)) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::sys_common::{AsInner, IntoInner}; - - use crate::rc::Rc; - use crate::sync::Arc; - - #[test] - fn test_os_string_with_capacity() { - let os_string = OsString::with_capacity(0); - assert_eq!(0, os_string.inner.into_inner().capacity()); - - let os_string = OsString::with_capacity(10); - assert_eq!(10, os_string.inner.into_inner().capacity()); - - let mut os_string = OsString::with_capacity(0); - os_string.push("abc"); - assert!(os_string.inner.into_inner().capacity() >= 3); - } - - #[test] - fn test_os_string_clear() { - let mut os_string = OsString::from("abc"); - assert_eq!(3, os_string.inner.as_inner().len()); - - os_string.clear(); - assert_eq!(&os_string, ""); - assert_eq!(0, os_string.inner.as_inner().len()); - } - - #[test] - fn test_os_string_capacity() { - let os_string = OsString::with_capacity(0); - assert_eq!(0, os_string.capacity()); - - let os_string = OsString::with_capacity(10); - assert_eq!(10, os_string.capacity()); - - let mut os_string = OsString::with_capacity(0); - os_string.push("abc"); - assert!(os_string.capacity() >= 3); - } - - #[test] - fn test_os_string_reserve() { - let mut os_string = OsString::new(); - assert_eq!(os_string.capacity(), 0); - - os_string.reserve(2); - assert!(os_string.capacity() >= 2); - - for _ in 0..16 { - os_string.push("a"); - } - - assert!(os_string.capacity() >= 16); - os_string.reserve(16); - assert!(os_string.capacity() >= 32); - - os_string.push("a"); - - os_string.reserve(16); - assert!(os_string.capacity() >= 33) - } - - #[test] - fn test_os_string_reserve_exact() { - let mut os_string = OsString::new(); - assert_eq!(os_string.capacity(), 0); - - os_string.reserve_exact(2); - assert!(os_string.capacity() >= 2); - - for _ in 0..16 { - os_string.push("a"); - } - - assert!(os_string.capacity() >= 16); - os_string.reserve_exact(16); - assert!(os_string.capacity() >= 32); - - os_string.push("a"); - - os_string.reserve_exact(16); - assert!(os_string.capacity() >= 33) - } - - #[test] - fn test_os_string_default() { - let os_string: OsString = Default::default(); - assert_eq!("", &os_string); - } - - #[test] - fn test_os_str_is_empty() { - let mut os_string = OsString::new(); - assert!(os_string.is_empty()); - - os_string.push("abc"); - assert!(!os_string.is_empty()); - - os_string.clear(); - assert!(os_string.is_empty()); - } - - #[test] - fn test_os_str_len() { - let mut os_string = OsString::new(); - assert_eq!(0, os_string.len()); - - os_string.push("abc"); - assert_eq!(3, os_string.len()); - - os_string.clear(); - assert_eq!(0, os_string.len()); - } - - #[test] - fn test_os_str_default() { - let os_str: &OsStr = Default::default(); - assert_eq!("", os_str); - } - - #[test] - fn into_boxed() { - let orig = "Hello, world!"; - let os_str = OsStr::new(orig); - let boxed: Box<OsStr> = Box::from(os_str); - let os_string = os_str.to_owned().into_boxed_os_str().into_os_string(); - assert_eq!(os_str, &*boxed); - assert_eq!(&*boxed, &*os_string); - assert_eq!(&*os_string, os_str); - } - - #[test] - fn boxed_default() { - let boxed = <Box<OsStr>>::default(); - assert!(boxed.is_empty()); - } - - #[test] - fn test_os_str_clone_into() { - let mut os_string = OsString::with_capacity(123); - os_string.push("hello"); - let os_str = OsStr::new("bonjour"); - os_str.clone_into(&mut os_string); - assert_eq!(os_str, os_string); - assert!(os_string.capacity() >= 123); - } - - #[test] - fn into_rc() { - let orig = "Hello, world!"; - let os_str = OsStr::new(orig); - let rc: Rc<OsStr> = Rc::from(os_str); - let arc: Arc<OsStr> = Arc::from(os_str); - - assert_eq!(&*rc, os_str); - assert_eq!(&*arc, os_str); - - let rc2: Rc<OsStr> = Rc::from(os_str.to_owned()); - let arc2: Arc<OsStr> = Arc::from(os_str.to_owned()); - - assert_eq!(&*rc2, os_str); - assert_eq!(&*arc2, os_str); - } -} diff --git a/library/std/src/ffi/os_str/tests.rs b/library/std/src/ffi/os_str/tests.rs new file mode 100644 index 00000000000..283f2b577e8 --- /dev/null +++ b/library/std/src/ffi/os_str/tests.rs @@ -0,0 +1,165 @@ +use super::*; +use crate::sys_common::{AsInner, IntoInner}; + +use crate::rc::Rc; +use crate::sync::Arc; + +#[test] +fn test_os_string_with_capacity() { + let os_string = OsString::with_capacity(0); + assert_eq!(0, os_string.inner.into_inner().capacity()); + + let os_string = OsString::with_capacity(10); + assert_eq!(10, os_string.inner.into_inner().capacity()); + + let mut os_string = OsString::with_capacity(0); + os_string.push("abc"); + assert!(os_string.inner.into_inner().capacity() >= 3); +} + +#[test] +fn test_os_string_clear() { + let mut os_string = OsString::from("abc"); + assert_eq!(3, os_string.inner.as_inner().len()); + + os_string.clear(); + assert_eq!(&os_string, ""); + assert_eq!(0, os_string.inner.as_inner().len()); +} + +#[test] +fn test_os_string_capacity() { + let os_string = OsString::with_capacity(0); + assert_eq!(0, os_string.capacity()); + + let os_string = OsString::with_capacity(10); + assert_eq!(10, os_string.capacity()); + + let mut os_string = OsString::with_capacity(0); + os_string.push("abc"); + assert!(os_string.capacity() >= 3); +} + +#[test] +fn test_os_string_reserve() { + let mut os_string = OsString::new(); + assert_eq!(os_string.capacity(), 0); + + os_string.reserve(2); + assert!(os_string.capacity() >= 2); + + for _ in 0..16 { + os_string.push("a"); + } + + assert!(os_string.capacity() >= 16); + os_string.reserve(16); + assert!(os_string.capacity() >= 32); + + os_string.push("a"); + + os_string.reserve(16); + assert!(os_string.capacity() >= 33) +} + +#[test] +fn test_os_string_reserve_exact() { + let mut os_string = OsString::new(); + assert_eq!(os_string.capacity(), 0); + + os_string.reserve_exact(2); + assert!(os_string.capacity() >= 2); + + for _ in 0..16 { + os_string.push("a"); + } + + assert!(os_string.capacity() >= 16); + os_string.reserve_exact(16); + assert!(os_string.capacity() >= 32); + + os_string.push("a"); + + os_string.reserve_exact(16); + assert!(os_string.capacity() >= 33) +} + +#[test] +fn test_os_string_default() { + let os_string: OsString = Default::default(); + assert_eq!("", &os_string); +} + +#[test] +fn test_os_str_is_empty() { + let mut os_string = OsString::new(); + assert!(os_string.is_empty()); + + os_string.push("abc"); + assert!(!os_string.is_empty()); + + os_string.clear(); + assert!(os_string.is_empty()); +} + +#[test] +fn test_os_str_len() { + let mut os_string = OsString::new(); + assert_eq!(0, os_string.len()); + + os_string.push("abc"); + assert_eq!(3, os_string.len()); + + os_string.clear(); + assert_eq!(0, os_string.len()); +} + +#[test] +fn test_os_str_default() { + let os_str: &OsStr = Default::default(); + assert_eq!("", os_str); +} + +#[test] +fn into_boxed() { + let orig = "Hello, world!"; + let os_str = OsStr::new(orig); + let boxed: Box<OsStr> = Box::from(os_str); + let os_string = os_str.to_owned().into_boxed_os_str().into_os_string(); + assert_eq!(os_str, &*boxed); + assert_eq!(&*boxed, &*os_string); + assert_eq!(&*os_string, os_str); +} + +#[test] +fn boxed_default() { + let boxed = <Box<OsStr>>::default(); + assert!(boxed.is_empty()); +} + +#[test] +fn test_os_str_clone_into() { + let mut os_string = OsString::with_capacity(123); + os_string.push("hello"); + let os_str = OsStr::new("bonjour"); + os_str.clone_into(&mut os_string); + assert_eq!(os_str, os_string); + assert!(os_string.capacity() >= 123); +} + +#[test] +fn into_rc() { + let orig = "Hello, world!"; + let os_str = OsStr::new(orig); + let rc: Rc<OsStr> = Rc::from(os_str); + let arc: Arc<OsStr> = Arc::from(os_str); + + assert_eq!(&*rc, os_str); + assert_eq!(&*arc, os_str); + + let rc2: Rc<OsStr> = Rc::from(os_str.to_owned()); + let arc2: Arc<OsStr> = Arc::from(os_str.to_owned()); + + assert_eq!(&*rc2, os_str); + assert_eq!(&*arc2, os_str); +} diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index b1630f8f549..161bfe3795c 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! Filesystem manipulation operations. //! //! This module contains basic methods to manipulate the contents of the local @@ -10,6 +8,9 @@ #![stable(feature = "rust1", since = "1.0.0")] #![deny(unsafe_op_in_unsafe_fn)] +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] +mod tests; + use crate::ffi::OsString; use crate::fmt; use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; @@ -552,7 +553,7 @@ impl File { /// the `SetFileInformationByHandle` function on Windows. Note that, this /// [may change in the future][changes]. /// - /// [changes]: ../io/index.html#platform-specific-behavior + /// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1502,7 +1503,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry { /// and the `DeleteFile` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1540,7 +1541,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> { /// and the `GetFileAttributesEx` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1574,7 +1575,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> { /// and the `GetFileAttributesEx` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1617,7 +1618,7 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> { /// /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1668,7 +1669,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> /// `fcopyfile`. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1706,7 +1707,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> { /// and the `CreateHardLink` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1771,7 +1772,7 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<( /// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1811,7 +1812,7 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> { /// with other applications (if passed to the application on the command-line, /// or written to a file another application may read). /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// [path]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file /// /// # Errors @@ -1845,7 +1846,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> { /// and the `CreateDirectory` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// **NOTE**: If a parent of the given path doesn't exist, this function will /// return an error. To create a directory and all its missing parents at the @@ -1886,7 +1887,7 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { /// and the `CreateDirectory` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1929,7 +1930,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> { /// and the `RemoveDirectory` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -1969,7 +1970,7 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { /// on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -2005,7 +2006,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> { /// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// The order in which this iterator returns entries is platform and filesystem /// dependent. @@ -2074,7 +2075,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> { /// and the `SetFileAttributes` function on Windows. /// Note that, this [may change in the future][changes]. /// -/// [changes]: ../io/index.html#platform-specific-behavior +/// [changes]: io#platform-specific-behavior /// /// # Errors /// @@ -2194,1349 +2195,3 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder { &mut self.inner } } - -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] -mod tests { - use crate::io::prelude::*; - - use crate::fs::{self, File, OpenOptions}; - use crate::io::{ErrorKind, SeekFrom}; - use crate::path::Path; - use crate::str; - use crate::sys_common::io::test::{tmpdir, TempDir}; - use crate::thread; - - use rand::{rngs::StdRng, RngCore, SeedableRng}; - - #[cfg(unix)] - use crate::os::unix::fs::symlink as symlink_dir; - #[cfg(unix)] - use crate::os::unix::fs::symlink as symlink_file; - #[cfg(unix)] - use crate::os::unix::fs::symlink as symlink_junction; - #[cfg(windows)] - use crate::os::windows::fs::{symlink_dir, symlink_file}; - #[cfg(windows)] - use crate::sys::fs::symlink_junction; - - macro_rules! check { - ($e:expr) => { - match $e { - Ok(t) => t, - Err(e) => panic!("{} failed with: {}", stringify!($e), e), - } - }; - } - - #[cfg(windows)] - macro_rules! error { - ($e:expr, $s:expr) => { - match $e { - Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s), - Err(ref err) => assert!( - err.raw_os_error() == Some($s), - format!("`{}` did not have a code of `{}`", err, $s) - ), - } - }; - } - - #[cfg(unix)] - macro_rules! error { - ($e:expr, $s:expr) => { - error_contains!($e, $s) - }; - } - - macro_rules! error_contains { - ($e:expr, $s:expr) => { - match $e { - Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s), - Err(ref err) => assert!( - err.to_string().contains($s), - format!("`{}` did not contain `{}`", err, $s) - ), - } - }; - } - - // Several test fail on windows if the user does not have permission to - // create symlinks (the `SeCreateSymbolicLinkPrivilege`). Instead of - // disabling these test on Windows, use this function to test whether we - // have permission, and return otherwise. This way, we still don't run these - // tests most of the time, but at least we do if the user has the right - // permissions. - pub fn got_symlink_permission(tmpdir: &TempDir) -> bool { - if cfg!(unix) { - return true; - } - let link = tmpdir.join("some_hopefully_unique_link_name"); - - match symlink_file(r"nonexisting_target", link) { - Ok(_) => true, - // ERROR_PRIVILEGE_NOT_HELD = 1314 - Err(ref err) if err.raw_os_error() == Some(1314) => false, - Err(_) => true, - } - } - - #[test] - fn file_test_io_smoke_test() { - let message = "it's alright. have a good time"; - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_rt_io_file_test.txt"); - { - let mut write_stream = check!(File::create(filename)); - check!(write_stream.write(message.as_bytes())); - } - { - let mut read_stream = check!(File::open(filename)); - let mut read_buf = [0; 1028]; - let read_str = match check!(read_stream.read(&mut read_buf)) { - 0 => panic!("shouldn't happen"), - n => str::from_utf8(&read_buf[..n]).unwrap().to_string(), - }; - assert_eq!(read_str, message); - } - check!(fs::remove_file(filename)); - } - - #[test] - fn invalid_path_raises() { - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_that_does_not_exist.txt"); - let result = File::open(filename); - - #[cfg(all(unix, not(target_os = "vxworks")))] - error!(result, "No such file or directory"); - #[cfg(target_os = "vxworks")] - error!(result, "no such file or directory"); - #[cfg(windows)] - error!(result, 2); // ERROR_FILE_NOT_FOUND - } - - #[test] - fn file_test_iounlinking_invalid_path_should_raise_condition() { - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt"); - - let result = fs::remove_file(filename); - - #[cfg(all(unix, not(target_os = "vxworks")))] - error!(result, "No such file or directory"); - #[cfg(target_os = "vxworks")] - error!(result, "no such file or directory"); - #[cfg(windows)] - error!(result, 2); // ERROR_FILE_NOT_FOUND - } - - #[test] - fn file_test_io_non_positional_read() { - let message: &str = "ten-four"; - let mut read_mem = [0; 8]; - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_rt_io_file_test_positional.txt"); - { - let mut rw_stream = check!(File::create(filename)); - check!(rw_stream.write(message.as_bytes())); - } - { - let mut read_stream = check!(File::open(filename)); - { - let read_buf = &mut read_mem[0..4]; - check!(read_stream.read(read_buf)); - } - { - let read_buf = &mut read_mem[4..8]; - check!(read_stream.read(read_buf)); - } - } - check!(fs::remove_file(filename)); - let read_str = str::from_utf8(&read_mem).unwrap(); - assert_eq!(read_str, message); - } - - #[test] - fn file_test_io_seek_and_tell_smoke_test() { - let message = "ten-four"; - let mut read_mem = [0; 4]; - let set_cursor = 4 as u64; - let tell_pos_pre_read; - let tell_pos_post_read; - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt"); - { - let mut rw_stream = check!(File::create(filename)); - check!(rw_stream.write(message.as_bytes())); - } - { - let mut read_stream = check!(File::open(filename)); - check!(read_stream.seek(SeekFrom::Start(set_cursor))); - tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0))); - check!(read_stream.read(&mut read_mem)); - tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0))); - } - check!(fs::remove_file(filename)); - let read_str = str::from_utf8(&read_mem).unwrap(); - assert_eq!(read_str, &message[4..8]); - assert_eq!(tell_pos_pre_read, set_cursor); - assert_eq!(tell_pos_post_read, message.len() as u64); - } - - #[test] - fn file_test_io_seek_and_write() { - let initial_msg = "food-is-yummy"; - let overwrite_msg = "-the-bar!!"; - let final_msg = "foo-the-bar!!"; - let seek_idx = 3; - let mut read_mem = [0; 13]; - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt"); - { - let mut rw_stream = check!(File::create(filename)); - check!(rw_stream.write(initial_msg.as_bytes())); - check!(rw_stream.seek(SeekFrom::Start(seek_idx))); - check!(rw_stream.write(overwrite_msg.as_bytes())); - } - { - let mut read_stream = check!(File::open(filename)); - check!(read_stream.read(&mut read_mem)); - } - check!(fs::remove_file(filename)); - let read_str = str::from_utf8(&read_mem).unwrap(); - assert!(read_str == final_msg); - } - - #[test] - fn file_test_io_seek_shakedown() { - // 01234567890123 - let initial_msg = "qwer-asdf-zxcv"; - let chunk_one: &str = "qwer"; - let chunk_two: &str = "asdf"; - let chunk_three: &str = "zxcv"; - let mut read_mem = [0; 4]; - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt"); - { - let mut rw_stream = check!(File::create(filename)); - check!(rw_stream.write(initial_msg.as_bytes())); - } - { - let mut read_stream = check!(File::open(filename)); - - check!(read_stream.seek(SeekFrom::End(-4))); - check!(read_stream.read(&mut read_mem)); - assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three); - - check!(read_stream.seek(SeekFrom::Current(-9))); - check!(read_stream.read(&mut read_mem)); - assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two); - - check!(read_stream.seek(SeekFrom::Start(0))); - check!(read_stream.read(&mut read_mem)); - assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one); - } - check!(fs::remove_file(filename)); - } - - #[test] - fn file_test_io_eof() { - let tmpdir = tmpdir(); - let filename = tmpdir.join("file_rt_io_file_test_eof.txt"); - let mut buf = [0; 256]; - { - let oo = OpenOptions::new().create_new(true).write(true).read(true).clone(); - let mut rw = check!(oo.open(&filename)); - assert_eq!(check!(rw.read(&mut buf)), 0); - assert_eq!(check!(rw.read(&mut buf)), 0); - } - check!(fs::remove_file(&filename)); - } - - #[test] - #[cfg(unix)] - fn file_test_io_read_write_at() { - use crate::os::unix::fs::FileExt; - - let tmpdir = tmpdir(); - let filename = tmpdir.join("file_rt_io_file_test_read_write_at.txt"); - let mut buf = [0; 256]; - let write1 = "asdf"; - let write2 = "qwer-"; - let write3 = "-zxcv"; - let content = "qwer-asdf-zxcv"; - { - let oo = OpenOptions::new().create_new(true).write(true).read(true).clone(); - let mut rw = check!(oo.open(&filename)); - assert_eq!(check!(rw.write_at(write1.as_bytes(), 5)), write1.len()); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0); - assert_eq!(check!(rw.read_at(&mut buf, 5)), write1.len()); - assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0); - assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len()); - assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok("\0\0\0\0\0")); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0); - assert_eq!(check!(rw.write(write2.as_bytes())), write2.len()); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5); - assert_eq!(check!(rw.read(&mut buf)), write1.len()); - assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); - assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len()); - assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2)); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); - assert_eq!(check!(rw.write_at(write3.as_bytes(), 9)), write3.len()); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); - } - { - let mut read = check!(File::open(&filename)); - assert_eq!(check!(read.read_at(&mut buf, 0)), content.len()); - assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 0); - assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9); - assert_eq!(check!(read.read_at(&mut buf, 0)), content.len()); - assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 9); - assert_eq!(check!(read.read(&mut buf)), write3.len()); - assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - assert_eq!(check!(read.read_at(&mut buf, 0)), content.len()); - assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - assert_eq!(check!(read.read_at(&mut buf, 14)), 0); - assert_eq!(check!(read.read_at(&mut buf, 15)), 0); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - } - check!(fs::remove_file(&filename)); - } - - #[test] - #[cfg(unix)] - fn set_get_unix_permissions() { - use crate::os::unix::fs::PermissionsExt; - - let tmpdir = tmpdir(); - let filename = &tmpdir.join("set_get_unix_permissions"); - check!(fs::create_dir(filename)); - let mask = 0o7777; - - check!(fs::set_permissions(filename, fs::Permissions::from_mode(0))); - let metadata0 = check!(fs::metadata(filename)); - assert_eq!(mask & metadata0.permissions().mode(), 0); - - check!(fs::set_permissions(filename, fs::Permissions::from_mode(0o1777))); - let metadata1 = check!(fs::metadata(filename)); - #[cfg(all(unix, not(target_os = "vxworks")))] - assert_eq!(mask & metadata1.permissions().mode(), 0o1777); - #[cfg(target_os = "vxworks")] - assert_eq!(mask & metadata1.permissions().mode(), 0o0777); - } - - #[test] - #[cfg(windows)] - fn file_test_io_seek_read_write() { - use crate::os::windows::fs::FileExt; - - let tmpdir = tmpdir(); - let filename = tmpdir.join("file_rt_io_file_test_seek_read_write.txt"); - let mut buf = [0; 256]; - let write1 = "asdf"; - let write2 = "qwer-"; - let write3 = "-zxcv"; - let content = "qwer-asdf-zxcv"; - { - let oo = OpenOptions::new().create_new(true).write(true).read(true).clone(); - let mut rw = check!(oo.open(&filename)); - assert_eq!(check!(rw.seek_write(write1.as_bytes(), 5)), write1.len()); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); - assert_eq!(check!(rw.seek_read(&mut buf, 5)), write1.len()); - assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); - assert_eq!(check!(rw.seek(SeekFrom::Start(0))), 0); - assert_eq!(check!(rw.write(write2.as_bytes())), write2.len()); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5); - assert_eq!(check!(rw.read(&mut buf)), write1.len()); - assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); - assert_eq!(check!(rw.seek_read(&mut buf[..write2.len()], 0)), write2.len()); - assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2)); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5); - assert_eq!(check!(rw.seek_write(write3.as_bytes(), 9)), write3.len()); - assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 14); - } - { - let mut read = check!(File::open(&filename)); - assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len()); - assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9); - assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len()); - assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9); - assert_eq!(check!(read.read(&mut buf)), write3.len()); - assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len()); - assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); - assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); - assert_eq!(check!(read.seek_read(&mut buf, 14)), 0); - assert_eq!(check!(read.seek_read(&mut buf, 15)), 0); - } - check!(fs::remove_file(&filename)); - } - - #[test] - fn file_test_stat_is_correct_on_is_file() { - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_stat_correct_on_is_file.txt"); - { - let mut opts = OpenOptions::new(); - let mut fs = check!(opts.read(true).write(true).create(true).open(filename)); - let msg = "hw"; - fs.write(msg.as_bytes()).unwrap(); - - let fstat_res = check!(fs.metadata()); - assert!(fstat_res.is_file()); - } - let stat_res_fn = check!(fs::metadata(filename)); - assert!(stat_res_fn.is_file()); - let stat_res_meth = check!(filename.metadata()); - assert!(stat_res_meth.is_file()); - check!(fs::remove_file(filename)); - } - - #[test] - fn file_test_stat_is_correct_on_is_dir() { - let tmpdir = tmpdir(); - let filename = &tmpdir.join("file_stat_correct_on_is_dir"); - check!(fs::create_dir(filename)); - let stat_res_fn = check!(fs::metadata(filename)); - assert!(stat_res_fn.is_dir()); - let stat_res_meth = check!(filename.metadata()); - assert!(stat_res_meth.is_dir()); - check!(fs::remove_dir(filename)); - } - - #[test] - fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() { - let tmpdir = tmpdir(); - let dir = &tmpdir.join("fileinfo_false_on_dir"); - check!(fs::create_dir(dir)); - assert!(!dir.is_file()); - check!(fs::remove_dir(dir)); - } - - #[test] - fn file_test_fileinfo_check_exists_before_and_after_file_creation() { - let tmpdir = tmpdir(); - let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt"); - check!(check!(File::create(file)).write(b"foo")); - assert!(file.exists()); - check!(fs::remove_file(file)); - assert!(!file.exists()); - } - - #[test] - fn file_test_directoryinfo_check_exists_before_and_after_mkdir() { - let tmpdir = tmpdir(); - let dir = &tmpdir.join("before_and_after_dir"); - assert!(!dir.exists()); - check!(fs::create_dir(dir)); - assert!(dir.exists()); - assert!(dir.is_dir()); - check!(fs::remove_dir(dir)); - assert!(!dir.exists()); - } - - #[test] - fn file_test_directoryinfo_readdir() { - let tmpdir = tmpdir(); - let dir = &tmpdir.join("di_readdir"); - check!(fs::create_dir(dir)); - let prefix = "foo"; - for n in 0..3 { - let f = dir.join(&format!("{}.txt", n)); - let mut w = check!(File::create(&f)); - let msg_str = format!("{}{}", prefix, n.to_string()); - let msg = msg_str.as_bytes(); - check!(w.write(msg)); - } - let files = check!(fs::read_dir(dir)); - let mut mem = [0; 4]; - for f in files { - let f = f.unwrap().path(); - { - let n = f.file_stem().unwrap(); - check!(check!(File::open(&f)).read(&mut mem)); - let read_str = str::from_utf8(&mem).unwrap(); - let expected = format!("{}{}", prefix, n.to_str().unwrap()); - assert_eq!(expected, read_str); - } - check!(fs::remove_file(&f)); - } - check!(fs::remove_dir(dir)); - } - - #[test] - fn file_create_new_already_exists_error() { - let tmpdir = tmpdir(); - let file = &tmpdir.join("file_create_new_error_exists"); - check!(fs::File::create(file)); - let e = fs::OpenOptions::new().write(true).create_new(true).open(file).unwrap_err(); - assert_eq!(e.kind(), ErrorKind::AlreadyExists); - } - - #[test] - fn mkdir_path_already_exists_error() { - let tmpdir = tmpdir(); - let dir = &tmpdir.join("mkdir_error_twice"); - check!(fs::create_dir(dir)); - let e = fs::create_dir(dir).unwrap_err(); - assert_eq!(e.kind(), ErrorKind::AlreadyExists); - } - - #[test] - fn recursive_mkdir() { - let tmpdir = tmpdir(); - let dir = tmpdir.join("d1/d2"); - check!(fs::create_dir_all(&dir)); - assert!(dir.is_dir()) - } - - #[test] - fn recursive_mkdir_failure() { - let tmpdir = tmpdir(); - let dir = tmpdir.join("d1"); - let file = dir.join("f1"); - - check!(fs::create_dir_all(&dir)); - check!(File::create(&file)); - - let result = fs::create_dir_all(&file); - - assert!(result.is_err()); - } - - #[test] - fn concurrent_recursive_mkdir() { - for _ in 0..100 { - let dir = tmpdir(); - let mut dir = dir.join("a"); - for _ in 0..40 { - dir = dir.join("a"); - } - let mut join = vec![]; - for _ in 0..8 { - let dir = dir.clone(); - join.push(thread::spawn(move || { - check!(fs::create_dir_all(&dir)); - })) - } - - // No `Display` on result of `join()` - join.drain(..).map(|join| join.join().unwrap()).count(); - } - } - - #[test] - fn recursive_mkdir_slash() { - check!(fs::create_dir_all(Path::new("/"))); - } - - #[test] - fn recursive_mkdir_dot() { - check!(fs::create_dir_all(Path::new("."))); - } - - #[test] - fn recursive_mkdir_empty() { - check!(fs::create_dir_all(Path::new(""))); - } - - #[test] - fn recursive_rmdir() { - let tmpdir = tmpdir(); - let d1 = tmpdir.join("d1"); - let dt = d1.join("t"); - let dtt = dt.join("t"); - let d2 = tmpdir.join("d2"); - let canary = d2.join("do_not_delete"); - check!(fs::create_dir_all(&dtt)); - check!(fs::create_dir_all(&d2)); - check!(check!(File::create(&canary)).write(b"foo")); - check!(symlink_junction(&d2, &dt.join("d2"))); - let _ = symlink_file(&canary, &d1.join("canary")); - check!(fs::remove_dir_all(&d1)); - - assert!(!d1.is_dir()); - assert!(canary.exists()); - } - - #[test] - fn recursive_rmdir_of_symlink() { - // test we do not recursively delete a symlink but only dirs. - let tmpdir = tmpdir(); - let link = tmpdir.join("d1"); - let dir = tmpdir.join("d2"); - let canary = dir.join("do_not_delete"); - check!(fs::create_dir_all(&dir)); - check!(check!(File::create(&canary)).write(b"foo")); - check!(symlink_junction(&dir, &link)); - check!(fs::remove_dir_all(&link)); - - assert!(!link.is_dir()); - assert!(canary.exists()); - } - - #[test] - // only Windows makes a distinction between file and directory symlinks. - #[cfg(windows)] - fn recursive_rmdir_of_file_symlink() { - let tmpdir = tmpdir(); - if !got_symlink_permission(&tmpdir) { - return; - }; - - let f1 = tmpdir.join("f1"); - let f2 = tmpdir.join("f2"); - check!(check!(File::create(&f1)).write(b"foo")); - check!(symlink_file(&f1, &f2)); - match fs::remove_dir_all(&f2) { - Ok(..) => panic!("wanted a failure"), - Err(..) => {} - } - } - - #[test] - fn unicode_path_is_dir() { - assert!(Path::new(".").is_dir()); - assert!(!Path::new("test/stdtest/fs.rs").is_dir()); - - let tmpdir = tmpdir(); - - let mut dirpath = tmpdir.path().to_path_buf(); - dirpath.push("test-가一ー你好"); - check!(fs::create_dir(&dirpath)); - assert!(dirpath.is_dir()); - - let mut filepath = dirpath; - filepath.push("unicode-file-\u{ac00}\u{4e00}\u{30fc}\u{4f60}\u{597d}.rs"); - check!(File::create(&filepath)); // ignore return; touch only - assert!(!filepath.is_dir()); - assert!(filepath.exists()); - } - - #[test] - fn unicode_path_exists() { - assert!(Path::new(".").exists()); - assert!(!Path::new("test/nonexistent-bogus-path").exists()); - - let tmpdir = tmpdir(); - let unicode = tmpdir.path(); - let unicode = unicode.join("test-각丁ー再见"); - check!(fs::create_dir(&unicode)); - assert!(unicode.exists()); - assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists()); - } - - #[test] - fn copy_file_does_not_exist() { - let from = Path::new("test/nonexistent-bogus-path"); - let to = Path::new("test/other-bogus-path"); - - match fs::copy(&from, &to) { - Ok(..) => panic!(), - Err(..) => { - assert!(!from.exists()); - assert!(!to.exists()); - } - } - } - - #[test] - fn copy_src_does_not_exist() { - let tmpdir = tmpdir(); - let from = Path::new("test/nonexistent-bogus-path"); - let to = tmpdir.join("out.txt"); - check!(check!(File::create(&to)).write(b"hello")); - assert!(fs::copy(&from, &to).is_err()); - assert!(!from.exists()); - let mut v = Vec::new(); - check!(check!(File::open(&to)).read_to_end(&mut v)); - assert_eq!(v, b"hello"); - } - - #[test] - fn copy_file_ok() { - let tmpdir = tmpdir(); - let input = tmpdir.join("in.txt"); - let out = tmpdir.join("out.txt"); - - check!(check!(File::create(&input)).write(b"hello")); - check!(fs::copy(&input, &out)); - let mut v = Vec::new(); - check!(check!(File::open(&out)).read_to_end(&mut v)); - assert_eq!(v, b"hello"); - - assert_eq!(check!(input.metadata()).permissions(), check!(out.metadata()).permissions()); - } - - #[test] - fn copy_file_dst_dir() { - let tmpdir = tmpdir(); - let out = tmpdir.join("out"); - - check!(File::create(&out)); - match fs::copy(&*out, tmpdir.path()) { - Ok(..) => panic!(), - Err(..) => {} - } - } - - #[test] - fn copy_file_dst_exists() { - let tmpdir = tmpdir(); - let input = tmpdir.join("in"); - let output = tmpdir.join("out"); - - check!(check!(File::create(&input)).write("foo".as_bytes())); - check!(check!(File::create(&output)).write("bar".as_bytes())); - check!(fs::copy(&input, &output)); - - let mut v = Vec::new(); - check!(check!(File::open(&output)).read_to_end(&mut v)); - assert_eq!(v, b"foo".to_vec()); - } - - #[test] - fn copy_file_src_dir() { - let tmpdir = tmpdir(); - let out = tmpdir.join("out"); - - match fs::copy(tmpdir.path(), &out) { - Ok(..) => panic!(), - Err(..) => {} - } - assert!(!out.exists()); - } - - #[test] - fn copy_file_preserves_perm_bits() { - let tmpdir = tmpdir(); - let input = tmpdir.join("in.txt"); - let out = tmpdir.join("out.txt"); - - let attr = check!(check!(File::create(&input)).metadata()); - let mut p = attr.permissions(); - p.set_readonly(true); - check!(fs::set_permissions(&input, p)); - check!(fs::copy(&input, &out)); - assert!(check!(out.metadata()).permissions().readonly()); - check!(fs::set_permissions(&input, attr.permissions())); - check!(fs::set_permissions(&out, attr.permissions())); - } - - #[test] - #[cfg(windows)] - fn copy_file_preserves_streams() { - let tmp = tmpdir(); - check!(check!(File::create(tmp.join("in.txt:bunny"))).write("carrot".as_bytes())); - assert_eq!(check!(fs::copy(tmp.join("in.txt"), tmp.join("out.txt"))), 0); - assert_eq!(check!(tmp.join("out.txt").metadata()).len(), 0); - let mut v = Vec::new(); - check!(check!(File::open(tmp.join("out.txt:bunny"))).read_to_end(&mut v)); - assert_eq!(v, b"carrot".to_vec()); - } - - #[test] - fn copy_file_returns_metadata_len() { - let tmp = tmpdir(); - let in_path = tmp.join("in.txt"); - let out_path = tmp.join("out.txt"); - check!(check!(File::create(&in_path)).write(b"lettuce")); - #[cfg(windows)] - check!(check!(File::create(tmp.join("in.txt:bunny"))).write(b"carrot")); - let copied_len = check!(fs::copy(&in_path, &out_path)); - assert_eq!(check!(out_path.metadata()).len(), copied_len); - } - - #[test] - fn copy_file_follows_dst_symlink() { - let tmp = tmpdir(); - if !got_symlink_permission(&tmp) { - return; - }; - - let in_path = tmp.join("in.txt"); - let out_path = tmp.join("out.txt"); - let out_path_symlink = tmp.join("out_symlink.txt"); - - check!(fs::write(&in_path, "foo")); - check!(fs::write(&out_path, "bar")); - check!(symlink_file(&out_path, &out_path_symlink)); - - check!(fs::copy(&in_path, &out_path_symlink)); - - assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink()); - assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec()); - assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec()); - } - - #[test] - fn symlinks_work() { - let tmpdir = tmpdir(); - if !got_symlink_permission(&tmpdir) { - return; - }; - - let input = tmpdir.join("in.txt"); - let out = tmpdir.join("out.txt"); - - check!(check!(File::create(&input)).write("foobar".as_bytes())); - check!(symlink_file(&input, &out)); - assert!(check!(out.symlink_metadata()).file_type().is_symlink()); - assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len()); - let mut v = Vec::new(); - check!(check!(File::open(&out)).read_to_end(&mut v)); - assert_eq!(v, b"foobar".to_vec()); - } - - #[test] - fn symlink_noexist() { - // Symlinks can point to things that don't exist - let tmpdir = tmpdir(); - if !got_symlink_permission(&tmpdir) { - return; - }; - - // Use a relative path for testing. Symlinks get normalized by Windows, - // so we may not get the same path back for absolute paths - check!(symlink_file(&"foo", &tmpdir.join("bar"))); - assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))).to_str().unwrap(), "foo"); - } - - #[test] - fn read_link() { - if cfg!(windows) { - // directory symlink - assert_eq!( - check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(), - r"C:\ProgramData" - ); - // junction - assert_eq!( - check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(), - r"C:\Users\Default" - ); - // junction with special permissions - assert_eq!( - check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(), - r"C:\Users" - ); - } - let tmpdir = tmpdir(); - let link = tmpdir.join("link"); - if !got_symlink_permission(&tmpdir) { - return; - }; - check!(symlink_file(&"foo", &link)); - assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo"); - } - - #[test] - fn readlink_not_symlink() { - let tmpdir = tmpdir(); - match fs::read_link(tmpdir.path()) { - Ok(..) => panic!("wanted a failure"), - Err(..) => {} - } - } - - #[test] - fn links_work() { - let tmpdir = tmpdir(); - let input = tmpdir.join("in.txt"); - let out = tmpdir.join("out.txt"); - - check!(check!(File::create(&input)).write("foobar".as_bytes())); - check!(fs::hard_link(&input, &out)); - assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len()); - assert_eq!(check!(fs::metadata(&out)).len(), check!(input.metadata()).len()); - let mut v = Vec::new(); - check!(check!(File::open(&out)).read_to_end(&mut v)); - assert_eq!(v, b"foobar".to_vec()); - - // can't link to yourself - match fs::hard_link(&input, &input) { - Ok(..) => panic!("wanted a failure"), - Err(..) => {} - } - // can't link to something that doesn't exist - match fs::hard_link(&tmpdir.join("foo"), &tmpdir.join("bar")) { - Ok(..) => panic!("wanted a failure"), - Err(..) => {} - } - } - - #[test] - fn chmod_works() { - let tmpdir = tmpdir(); - let file = tmpdir.join("in.txt"); - - check!(File::create(&file)); - let attr = check!(fs::metadata(&file)); - assert!(!attr.permissions().readonly()); - let mut p = attr.permissions(); - p.set_readonly(true); - check!(fs::set_permissions(&file, p.clone())); - let attr = check!(fs::metadata(&file)); - assert!(attr.permissions().readonly()); - - match fs::set_permissions(&tmpdir.join("foo"), p.clone()) { - Ok(..) => panic!("wanted an error"), - Err(..) => {} - } - - p.set_readonly(false); - check!(fs::set_permissions(&file, p)); - } - - #[test] - fn fchmod_works() { - let tmpdir = tmpdir(); - let path = tmpdir.join("in.txt"); - - let file = check!(File::create(&path)); - let attr = check!(fs::metadata(&path)); - assert!(!attr.permissions().readonly()); - let mut p = attr.permissions(); - p.set_readonly(true); - check!(file.set_permissions(p.clone())); - let attr = check!(fs::metadata(&path)); - assert!(attr.permissions().readonly()); - - p.set_readonly(false); - check!(file.set_permissions(p)); - } - - #[test] - fn sync_doesnt_kill_anything() { - let tmpdir = tmpdir(); - let path = tmpdir.join("in.txt"); - - let mut file = check!(File::create(&path)); - check!(file.sync_all()); - check!(file.sync_data()); - check!(file.write(b"foo")); - check!(file.sync_all()); - check!(file.sync_data()); - } - - #[test] - fn truncate_works() { - let tmpdir = tmpdir(); - let path = tmpdir.join("in.txt"); - - let mut file = check!(File::create(&path)); - check!(file.write(b"foo")); - check!(file.sync_all()); - - // Do some simple things with truncation - assert_eq!(check!(file.metadata()).len(), 3); - check!(file.set_len(10)); - assert_eq!(check!(file.metadata()).len(), 10); - check!(file.write(b"bar")); - check!(file.sync_all()); - assert_eq!(check!(file.metadata()).len(), 10); - - let mut v = Vec::new(); - check!(check!(File::open(&path)).read_to_end(&mut v)); - assert_eq!(v, b"foobar\0\0\0\0".to_vec()); - - // Truncate to a smaller length, don't seek, and then write something. - // Ensure that the intermediate zeroes are all filled in (we have `seek`ed - // past the end of the file). - check!(file.set_len(2)); - assert_eq!(check!(file.metadata()).len(), 2); - check!(file.write(b"wut")); - check!(file.sync_all()); - assert_eq!(check!(file.metadata()).len(), 9); - let mut v = Vec::new(); - check!(check!(File::open(&path)).read_to_end(&mut v)); - assert_eq!(v, b"fo\0\0\0\0wut".to_vec()); - } - - #[test] - fn open_flavors() { - use crate::fs::OpenOptions as OO; - fn c<T: Clone>(t: &T) -> T { - t.clone() - } - - let tmpdir = tmpdir(); - - let mut r = OO::new(); - r.read(true); - let mut w = OO::new(); - w.write(true); - let mut rw = OO::new(); - rw.read(true).write(true); - let mut a = OO::new(); - a.append(true); - let mut ra = OO::new(); - ra.read(true).append(true); - - #[cfg(windows)] - let invalid_options = 87; // ERROR_INVALID_PARAMETER - #[cfg(all(unix, not(target_os = "vxworks")))] - let invalid_options = "Invalid argument"; - #[cfg(target_os = "vxworks")] - let invalid_options = "invalid argument"; - - // Test various combinations of creation modes and access modes. - // - // Allowed: - // creation mode | read | write | read-write | append | read-append | - // :-----------------------|:-----:|:-----:|:----------:|:------:|:-----------:| - // not set (open existing) | X | X | X | X | X | - // create | | X | X | X | X | - // truncate | | X | X | | | - // create and truncate | | X | X | | | - // create_new | | X | X | X | X | - // - // tested in reverse order, so 'create_new' creates the file, and 'open existing' opens it. - - // write-only - check!(c(&w).create_new(true).open(&tmpdir.join("a"))); - check!(c(&w).create(true).truncate(true).open(&tmpdir.join("a"))); - check!(c(&w).truncate(true).open(&tmpdir.join("a"))); - check!(c(&w).create(true).open(&tmpdir.join("a"))); - check!(c(&w).open(&tmpdir.join("a"))); - - // read-only - error!(c(&r).create_new(true).open(&tmpdir.join("b")), invalid_options); - error!(c(&r).create(true).truncate(true).open(&tmpdir.join("b")), invalid_options); - error!(c(&r).truncate(true).open(&tmpdir.join("b")), invalid_options); - error!(c(&r).create(true).open(&tmpdir.join("b")), invalid_options); - check!(c(&r).open(&tmpdir.join("a"))); // try opening the file created with write_only - - // read-write - check!(c(&rw).create_new(true).open(&tmpdir.join("c"))); - check!(c(&rw).create(true).truncate(true).open(&tmpdir.join("c"))); - check!(c(&rw).truncate(true).open(&tmpdir.join("c"))); - check!(c(&rw).create(true).open(&tmpdir.join("c"))); - check!(c(&rw).open(&tmpdir.join("c"))); - - // append - check!(c(&a).create_new(true).open(&tmpdir.join("d"))); - error!(c(&a).create(true).truncate(true).open(&tmpdir.join("d")), invalid_options); - error!(c(&a).truncate(true).open(&tmpdir.join("d")), invalid_options); - check!(c(&a).create(true).open(&tmpdir.join("d"))); - check!(c(&a).open(&tmpdir.join("d"))); - - // read-append - check!(c(&ra).create_new(true).open(&tmpdir.join("e"))); - error!(c(&ra).create(true).truncate(true).open(&tmpdir.join("e")), invalid_options); - error!(c(&ra).truncate(true).open(&tmpdir.join("e")), invalid_options); - check!(c(&ra).create(true).open(&tmpdir.join("e"))); - check!(c(&ra).open(&tmpdir.join("e"))); - - // Test opening a file without setting an access mode - let mut blank = OO::new(); - error!(blank.create(true).open(&tmpdir.join("f")), invalid_options); - - // Test write works - check!(check!(File::create(&tmpdir.join("h"))).write("foobar".as_bytes())); - - // Test write fails for read-only - check!(r.open(&tmpdir.join("h"))); - { - let mut f = check!(r.open(&tmpdir.join("h"))); - assert!(f.write("wut".as_bytes()).is_err()); - } - - // Test write overwrites - { - let mut f = check!(c(&w).open(&tmpdir.join("h"))); - check!(f.write("baz".as_bytes())); - } - { - let mut f = check!(c(&r).open(&tmpdir.join("h"))); - let mut b = vec![0; 6]; - check!(f.read(&mut b)); - assert_eq!(b, "bazbar".as_bytes()); - } - - // Test truncate works - { - let mut f = check!(c(&w).truncate(true).open(&tmpdir.join("h"))); - check!(f.write("foo".as_bytes())); - } - assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3); - - // Test append works - assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3); - { - let mut f = check!(c(&a).open(&tmpdir.join("h"))); - check!(f.write("bar".as_bytes())); - } - assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 6); - - // Test .append(true) equals .write(true).append(true) - { - let mut f = check!(c(&w).append(true).open(&tmpdir.join("h"))); - check!(f.write("baz".as_bytes())); - } - assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 9); - } - - #[test] - fn _assert_send_sync() { - fn _assert_send_sync<T: Send + Sync>() {} - _assert_send_sync::<OpenOptions>(); - } - - #[test] - fn binary_file() { - let mut bytes = [0; 1024]; - StdRng::from_entropy().fill_bytes(&mut bytes); - - let tmpdir = tmpdir(); - - check!(check!(File::create(&tmpdir.join("test"))).write(&bytes)); - let mut v = Vec::new(); - check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v)); - assert!(v == &bytes[..]); - } - - #[test] - fn write_then_read() { - let mut bytes = [0; 1024]; - StdRng::from_entropy().fill_bytes(&mut bytes); - - let tmpdir = tmpdir(); - - check!(fs::write(&tmpdir.join("test"), &bytes[..])); - let v = check!(fs::read(&tmpdir.join("test"))); - assert!(v == &bytes[..]); - - check!(fs::write(&tmpdir.join("not-utf8"), &[0xFF])); - error_contains!( - fs::read_to_string(&tmpdir.join("not-utf8")), - "stream did not contain valid UTF-8" - ); - - let s = "𐁁𐀓𐀠𐀴𐀍"; - check!(fs::write(&tmpdir.join("utf8"), s.as_bytes())); - let string = check!(fs::read_to_string(&tmpdir.join("utf8"))); - assert_eq!(string, s); - } - - #[test] - fn file_try_clone() { - let tmpdir = tmpdir(); - - let mut f1 = check!( - OpenOptions::new().read(true).write(true).create(true).open(&tmpdir.join("test")) - ); - let mut f2 = check!(f1.try_clone()); - - check!(f1.write_all(b"hello world")); - check!(f1.seek(SeekFrom::Start(2))); - - let mut buf = vec![]; - check!(f2.read_to_end(&mut buf)); - assert_eq!(buf, b"llo world"); - drop(f2); - - check!(f1.write_all(b"!")); - } - - #[test] - #[cfg(not(windows))] - fn unlink_readonly() { - let tmpdir = tmpdir(); - let path = tmpdir.join("file"); - check!(File::create(&path)); - let mut perm = check!(fs::metadata(&path)).permissions(); - perm.set_readonly(true); - check!(fs::set_permissions(&path, perm)); - check!(fs::remove_file(&path)); - } - - #[test] - fn mkdir_trailing_slash() { - let tmpdir = tmpdir(); - let path = tmpdir.join("file"); - check!(fs::create_dir_all(&path.join("a/"))); - } - - #[test] - fn canonicalize_works_simple() { - let tmpdir = tmpdir(); - let tmpdir = fs::canonicalize(tmpdir.path()).unwrap(); - let file = tmpdir.join("test"); - File::create(&file).unwrap(); - assert_eq!(fs::canonicalize(&file).unwrap(), file); - } - - #[test] - fn realpath_works() { - let tmpdir = tmpdir(); - if !got_symlink_permission(&tmpdir) { - return; - }; - - let tmpdir = fs::canonicalize(tmpdir.path()).unwrap(); - let file = tmpdir.join("test"); - let dir = tmpdir.join("test2"); - let link = dir.join("link"); - let linkdir = tmpdir.join("test3"); - - File::create(&file).unwrap(); - fs::create_dir(&dir).unwrap(); - symlink_file(&file, &link).unwrap(); - symlink_dir(&dir, &linkdir).unwrap(); - - assert!(link.symlink_metadata().unwrap().file_type().is_symlink()); - - assert_eq!(fs::canonicalize(&tmpdir).unwrap(), tmpdir); - assert_eq!(fs::canonicalize(&file).unwrap(), file); - assert_eq!(fs::canonicalize(&link).unwrap(), file); - assert_eq!(fs::canonicalize(&linkdir).unwrap(), dir); - assert_eq!(fs::canonicalize(&linkdir.join("link")).unwrap(), file); - } - - #[test] - fn realpath_works_tricky() { - let tmpdir = tmpdir(); - if !got_symlink_permission(&tmpdir) { - return; - }; - - let tmpdir = fs::canonicalize(tmpdir.path()).unwrap(); - let a = tmpdir.join("a"); - let b = a.join("b"); - let c = b.join("c"); - let d = a.join("d"); - let e = d.join("e"); - let f = a.join("f"); - - fs::create_dir_all(&b).unwrap(); - fs::create_dir_all(&d).unwrap(); - File::create(&f).unwrap(); - if cfg!(not(windows)) { - symlink_file("../d/e", &c).unwrap(); - symlink_file("../f", &e).unwrap(); - } - if cfg!(windows) { - symlink_file(r"..\d\e", &c).unwrap(); - symlink_file(r"..\f", &e).unwrap(); - } - - assert_eq!(fs::canonicalize(&c).unwrap(), f); - assert_eq!(fs::canonicalize(&e).unwrap(), f); - } - - #[test] - fn dir_entry_methods() { - let tmpdir = tmpdir(); - - fs::create_dir_all(&tmpdir.join("a")).unwrap(); - File::create(&tmpdir.join("b")).unwrap(); - - for file in tmpdir.path().read_dir().unwrap().map(|f| f.unwrap()) { - let fname = file.file_name(); - match fname.to_str() { - Some("a") => { - assert!(file.file_type().unwrap().is_dir()); - assert!(file.metadata().unwrap().is_dir()); - } - Some("b") => { - assert!(file.file_type().unwrap().is_file()); - assert!(file.metadata().unwrap().is_file()); - } - f => panic!("unknown file name: {:?}", f), - } - } - } - - #[test] - fn dir_entry_debug() { - let tmpdir = tmpdir(); - File::create(&tmpdir.join("b")).unwrap(); - let mut read_dir = tmpdir.path().read_dir().unwrap(); - let dir_entry = read_dir.next().unwrap().unwrap(); - let actual = format!("{:?}", dir_entry); - let expected = format!("DirEntry({:?})", dir_entry.0.path()); - assert_eq!(actual, expected); - } - - #[test] - fn read_dir_not_found() { - let res = fs::read_dir("/path/that/does/not/exist"); - assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound); - } - - #[test] - fn create_dir_all_with_junctions() { - let tmpdir = tmpdir(); - let target = tmpdir.join("target"); - - let junction = tmpdir.join("junction"); - let b = junction.join("a/b"); - - let link = tmpdir.join("link"); - let d = link.join("c/d"); - - fs::create_dir(&target).unwrap(); - - check!(symlink_junction(&target, &junction)); - check!(fs::create_dir_all(&b)); - // the junction itself is not a directory, but `is_dir()` on a Path - // follows links - assert!(junction.is_dir()); - assert!(b.exists()); - - if !got_symlink_permission(&tmpdir) { - return; - }; - check!(symlink_dir(&target, &link)); - check!(fs::create_dir_all(&d)); - assert!(link.is_dir()); - assert!(d.exists()); - } - - #[test] - fn metadata_access_times() { - let tmpdir = tmpdir(); - - let b = tmpdir.join("b"); - File::create(&b).unwrap(); - - let a = check!(fs::metadata(&tmpdir.path())); - let b = check!(fs::metadata(&b)); - - assert_eq!(check!(a.accessed()), check!(a.accessed())); - assert_eq!(check!(a.modified()), check!(a.modified())); - assert_eq!(check!(b.accessed()), check!(b.modified())); - - if cfg!(target_os = "macos") || cfg!(target_os = "windows") { - check!(a.created()); - check!(b.created()); - } - - if cfg!(target_os = "linux") { - // Not always available - match (a.created(), b.created()) { - (Ok(t1), Ok(t2)) => assert!(t1 <= t2), - (Err(e1), Err(e2)) - if e1.kind() == ErrorKind::Other && e2.kind() == ErrorKind::Other => {} - (a, b) => panic!( - "creation time must be always supported or not supported: {:?} {:?}", - a, b, - ), - } - } - } -} diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs new file mode 100644 index 00000000000..65a29076fef --- /dev/null +++ b/library/std/src/fs/tests.rs @@ -0,0 +1,1339 @@ +use crate::io::prelude::*; + +use crate::fs::{self, File, OpenOptions}; +use crate::io::{ErrorKind, SeekFrom}; +use crate::path::Path; +use crate::str; +use crate::sys_common::io::test::{tmpdir, TempDir}; +use crate::thread; + +use rand::{rngs::StdRng, RngCore, SeedableRng}; + +#[cfg(unix)] +use crate::os::unix::fs::symlink as symlink_dir; +#[cfg(unix)] +use crate::os::unix::fs::symlink as symlink_file; +#[cfg(unix)] +use crate::os::unix::fs::symlink as symlink_junction; +#[cfg(windows)] +use crate::os::windows::fs::{symlink_dir, symlink_file}; +#[cfg(windows)] +use crate::sys::fs::symlink_junction; + +macro_rules! check { + ($e:expr) => { + match $e { + Ok(t) => t, + Err(e) => panic!("{} failed with: {}", stringify!($e), e), + } + }; +} + +#[cfg(windows)] +macro_rules! error { + ($e:expr, $s:expr) => { + match $e { + Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s), + Err(ref err) => assert!( + err.raw_os_error() == Some($s), + format!("`{}` did not have a code of `{}`", err, $s) + ), + } + }; +} + +#[cfg(unix)] +macro_rules! error { + ($e:expr, $s:expr) => { + error_contains!($e, $s) + }; +} + +macro_rules! error_contains { + ($e:expr, $s:expr) => { + match $e { + Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s), + Err(ref err) => { + assert!(err.to_string().contains($s), format!("`{}` did not contain `{}`", err, $s)) + } + } + }; +} + +// Several test fail on windows if the user does not have permission to +// create symlinks (the `SeCreateSymbolicLinkPrivilege`). Instead of +// disabling these test on Windows, use this function to test whether we +// have permission, and return otherwise. This way, we still don't run these +// tests most of the time, but at least we do if the user has the right +// permissions. +pub fn got_symlink_permission(tmpdir: &TempDir) -> bool { + if cfg!(unix) { + return true; + } + let link = tmpdir.join("some_hopefully_unique_link_name"); + + match symlink_file(r"nonexisting_target", link) { + Ok(_) => true, + // ERROR_PRIVILEGE_NOT_HELD = 1314 + Err(ref err) if err.raw_os_error() == Some(1314) => false, + Err(_) => true, + } +} + +#[test] +fn file_test_io_smoke_test() { + let message = "it's alright. have a good time"; + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_rt_io_file_test.txt"); + { + let mut write_stream = check!(File::create(filename)); + check!(write_stream.write(message.as_bytes())); + } + { + let mut read_stream = check!(File::open(filename)); + let mut read_buf = [0; 1028]; + let read_str = match check!(read_stream.read(&mut read_buf)) { + 0 => panic!("shouldn't happen"), + n => str::from_utf8(&read_buf[..n]).unwrap().to_string(), + }; + assert_eq!(read_str, message); + } + check!(fs::remove_file(filename)); +} + +#[test] +fn invalid_path_raises() { + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_that_does_not_exist.txt"); + let result = File::open(filename); + + #[cfg(all(unix, not(target_os = "vxworks")))] + error!(result, "No such file or directory"); + #[cfg(target_os = "vxworks")] + error!(result, "no such file or directory"); + #[cfg(windows)] + error!(result, 2); // ERROR_FILE_NOT_FOUND +} + +#[test] +fn file_test_iounlinking_invalid_path_should_raise_condition() { + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt"); + + let result = fs::remove_file(filename); + + #[cfg(all(unix, not(target_os = "vxworks")))] + error!(result, "No such file or directory"); + #[cfg(target_os = "vxworks")] + error!(result, "no such file or directory"); + #[cfg(windows)] + error!(result, 2); // ERROR_FILE_NOT_FOUND +} + +#[test] +fn file_test_io_non_positional_read() { + let message: &str = "ten-four"; + let mut read_mem = [0; 8]; + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_rt_io_file_test_positional.txt"); + { + let mut rw_stream = check!(File::create(filename)); + check!(rw_stream.write(message.as_bytes())); + } + { + let mut read_stream = check!(File::open(filename)); + { + let read_buf = &mut read_mem[0..4]; + check!(read_stream.read(read_buf)); + } + { + let read_buf = &mut read_mem[4..8]; + check!(read_stream.read(read_buf)); + } + } + check!(fs::remove_file(filename)); + let read_str = str::from_utf8(&read_mem).unwrap(); + assert_eq!(read_str, message); +} + +#[test] +fn file_test_io_seek_and_tell_smoke_test() { + let message = "ten-four"; + let mut read_mem = [0; 4]; + let set_cursor = 4 as u64; + let tell_pos_pre_read; + let tell_pos_post_read; + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt"); + { + let mut rw_stream = check!(File::create(filename)); + check!(rw_stream.write(message.as_bytes())); + } + { + let mut read_stream = check!(File::open(filename)); + check!(read_stream.seek(SeekFrom::Start(set_cursor))); + tell_pos_pre_read = check!(read_stream.seek(SeekFrom::Current(0))); + check!(read_stream.read(&mut read_mem)); + tell_pos_post_read = check!(read_stream.seek(SeekFrom::Current(0))); + } + check!(fs::remove_file(filename)); + let read_str = str::from_utf8(&read_mem).unwrap(); + assert_eq!(read_str, &message[4..8]); + assert_eq!(tell_pos_pre_read, set_cursor); + assert_eq!(tell_pos_post_read, message.len() as u64); +} + +#[test] +fn file_test_io_seek_and_write() { + let initial_msg = "food-is-yummy"; + let overwrite_msg = "-the-bar!!"; + let final_msg = "foo-the-bar!!"; + let seek_idx = 3; + let mut read_mem = [0; 13]; + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt"); + { + let mut rw_stream = check!(File::create(filename)); + check!(rw_stream.write(initial_msg.as_bytes())); + check!(rw_stream.seek(SeekFrom::Start(seek_idx))); + check!(rw_stream.write(overwrite_msg.as_bytes())); + } + { + let mut read_stream = check!(File::open(filename)); + check!(read_stream.read(&mut read_mem)); + } + check!(fs::remove_file(filename)); + let read_str = str::from_utf8(&read_mem).unwrap(); + assert!(read_str == final_msg); +} + +#[test] +fn file_test_io_seek_shakedown() { + // 01234567890123 + let initial_msg = "qwer-asdf-zxcv"; + let chunk_one: &str = "qwer"; + let chunk_two: &str = "asdf"; + let chunk_three: &str = "zxcv"; + let mut read_mem = [0; 4]; + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt"); + { + let mut rw_stream = check!(File::create(filename)); + check!(rw_stream.write(initial_msg.as_bytes())); + } + { + let mut read_stream = check!(File::open(filename)); + + check!(read_stream.seek(SeekFrom::End(-4))); + check!(read_stream.read(&mut read_mem)); + assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_three); + + check!(read_stream.seek(SeekFrom::Current(-9))); + check!(read_stream.read(&mut read_mem)); + assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_two); + + check!(read_stream.seek(SeekFrom::Start(0))); + check!(read_stream.read(&mut read_mem)); + assert_eq!(str::from_utf8(&read_mem).unwrap(), chunk_one); + } + check!(fs::remove_file(filename)); +} + +#[test] +fn file_test_io_eof() { + let tmpdir = tmpdir(); + let filename = tmpdir.join("file_rt_io_file_test_eof.txt"); + let mut buf = [0; 256]; + { + let oo = OpenOptions::new().create_new(true).write(true).read(true).clone(); + let mut rw = check!(oo.open(&filename)); + assert_eq!(check!(rw.read(&mut buf)), 0); + assert_eq!(check!(rw.read(&mut buf)), 0); + } + check!(fs::remove_file(&filename)); +} + +#[test] +#[cfg(unix)] +fn file_test_io_read_write_at() { + use crate::os::unix::fs::FileExt; + + let tmpdir = tmpdir(); + let filename = tmpdir.join("file_rt_io_file_test_read_write_at.txt"); + let mut buf = [0; 256]; + let write1 = "asdf"; + let write2 = "qwer-"; + let write3 = "-zxcv"; + let content = "qwer-asdf-zxcv"; + { + let oo = OpenOptions::new().create_new(true).write(true).read(true).clone(); + let mut rw = check!(oo.open(&filename)); + assert_eq!(check!(rw.write_at(write1.as_bytes(), 5)), write1.len()); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0); + assert_eq!(check!(rw.read_at(&mut buf, 5)), write1.len()); + assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0); + assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len()); + assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok("\0\0\0\0\0")); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 0); + assert_eq!(check!(rw.write(write2.as_bytes())), write2.len()); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5); + assert_eq!(check!(rw.read(&mut buf)), write1.len()); + assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); + assert_eq!(check!(rw.read_at(&mut buf[..write2.len()], 0)), write2.len()); + assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2)); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); + assert_eq!(check!(rw.write_at(write3.as_bytes(), 9)), write3.len()); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); + } + { + let mut read = check!(File::open(&filename)); + assert_eq!(check!(read.read_at(&mut buf, 0)), content.len()); + assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 0); + assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9); + assert_eq!(check!(read.read_at(&mut buf, 0)), content.len()); + assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 9); + assert_eq!(check!(read.read(&mut buf)), write3.len()); + assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + assert_eq!(check!(read.read_at(&mut buf, 0)), content.len()); + assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + assert_eq!(check!(read.read_at(&mut buf, 14)), 0); + assert_eq!(check!(read.read_at(&mut buf, 15)), 0); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + } + check!(fs::remove_file(&filename)); +} + +#[test] +#[cfg(unix)] +fn set_get_unix_permissions() { + use crate::os::unix::fs::PermissionsExt; + + let tmpdir = tmpdir(); + let filename = &tmpdir.join("set_get_unix_permissions"); + check!(fs::create_dir(filename)); + let mask = 0o7777; + + check!(fs::set_permissions(filename, fs::Permissions::from_mode(0))); + let metadata0 = check!(fs::metadata(filename)); + assert_eq!(mask & metadata0.permissions().mode(), 0); + + check!(fs::set_permissions(filename, fs::Permissions::from_mode(0o1777))); + let metadata1 = check!(fs::metadata(filename)); + #[cfg(all(unix, not(target_os = "vxworks")))] + assert_eq!(mask & metadata1.permissions().mode(), 0o1777); + #[cfg(target_os = "vxworks")] + assert_eq!(mask & metadata1.permissions().mode(), 0o0777); +} + +#[test] +#[cfg(windows)] +fn file_test_io_seek_read_write() { + use crate::os::windows::fs::FileExt; + + let tmpdir = tmpdir(); + let filename = tmpdir.join("file_rt_io_file_test_seek_read_write.txt"); + let mut buf = [0; 256]; + let write1 = "asdf"; + let write2 = "qwer-"; + let write3 = "-zxcv"; + let content = "qwer-asdf-zxcv"; + { + let oo = OpenOptions::new().create_new(true).write(true).read(true).clone(); + let mut rw = check!(oo.open(&filename)); + assert_eq!(check!(rw.seek_write(write1.as_bytes(), 5)), write1.len()); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); + assert_eq!(check!(rw.seek_read(&mut buf, 5)), write1.len()); + assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); + assert_eq!(check!(rw.seek(SeekFrom::Start(0))), 0); + assert_eq!(check!(rw.write(write2.as_bytes())), write2.len()); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5); + assert_eq!(check!(rw.read(&mut buf)), write1.len()); + assert_eq!(str::from_utf8(&buf[..write1.len()]), Ok(write1)); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 9); + assert_eq!(check!(rw.seek_read(&mut buf[..write2.len()], 0)), write2.len()); + assert_eq!(str::from_utf8(&buf[..write2.len()]), Ok(write2)); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 5); + assert_eq!(check!(rw.seek_write(write3.as_bytes(), 9)), write3.len()); + assert_eq!(check!(rw.seek(SeekFrom::Current(0))), 14); + } + { + let mut read = check!(File::open(&filename)); + assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len()); + assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9); + assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len()); + assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + assert_eq!(check!(read.seek(SeekFrom::End(-5))), 9); + assert_eq!(check!(read.read(&mut buf)), write3.len()); + assert_eq!(str::from_utf8(&buf[..write3.len()]), Ok(write3)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + assert_eq!(check!(read.seek_read(&mut buf, 0)), content.len()); + assert_eq!(str::from_utf8(&buf[..content.len()]), Ok(content)); + assert_eq!(check!(read.seek(SeekFrom::Current(0))), 14); + assert_eq!(check!(read.seek_read(&mut buf, 14)), 0); + assert_eq!(check!(read.seek_read(&mut buf, 15)), 0); + } + check!(fs::remove_file(&filename)); +} + +#[test] +fn file_test_stat_is_correct_on_is_file() { + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_stat_correct_on_is_file.txt"); + { + let mut opts = OpenOptions::new(); + let mut fs = check!(opts.read(true).write(true).create(true).open(filename)); + let msg = "hw"; + fs.write(msg.as_bytes()).unwrap(); + + let fstat_res = check!(fs.metadata()); + assert!(fstat_res.is_file()); + } + let stat_res_fn = check!(fs::metadata(filename)); + assert!(stat_res_fn.is_file()); + let stat_res_meth = check!(filename.metadata()); + assert!(stat_res_meth.is_file()); + check!(fs::remove_file(filename)); +} + +#[test] +fn file_test_stat_is_correct_on_is_dir() { + let tmpdir = tmpdir(); + let filename = &tmpdir.join("file_stat_correct_on_is_dir"); + check!(fs::create_dir(filename)); + let stat_res_fn = check!(fs::metadata(filename)); + assert!(stat_res_fn.is_dir()); + let stat_res_meth = check!(filename.metadata()); + assert!(stat_res_meth.is_dir()); + check!(fs::remove_dir(filename)); +} + +#[test] +fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() { + let tmpdir = tmpdir(); + let dir = &tmpdir.join("fileinfo_false_on_dir"); + check!(fs::create_dir(dir)); + assert!(!dir.is_file()); + check!(fs::remove_dir(dir)); +} + +#[test] +fn file_test_fileinfo_check_exists_before_and_after_file_creation() { + let tmpdir = tmpdir(); + let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt"); + check!(check!(File::create(file)).write(b"foo")); + assert!(file.exists()); + check!(fs::remove_file(file)); + assert!(!file.exists()); +} + +#[test] +fn file_test_directoryinfo_check_exists_before_and_after_mkdir() { + let tmpdir = tmpdir(); + let dir = &tmpdir.join("before_and_after_dir"); + assert!(!dir.exists()); + check!(fs::create_dir(dir)); + assert!(dir.exists()); + assert!(dir.is_dir()); + check!(fs::remove_dir(dir)); + assert!(!dir.exists()); +} + +#[test] +fn file_test_directoryinfo_readdir() { + let tmpdir = tmpdir(); + let dir = &tmpdir.join("di_readdir"); + check!(fs::create_dir(dir)); + let prefix = "foo"; + for n in 0..3 { + let f = dir.join(&format!("{}.txt", n)); + let mut w = check!(File::create(&f)); + let msg_str = format!("{}{}", prefix, n.to_string()); + let msg = msg_str.as_bytes(); + check!(w.write(msg)); + } + let files = check!(fs::read_dir(dir)); + let mut mem = [0; 4]; + for f in files { + let f = f.unwrap().path(); + { + let n = f.file_stem().unwrap(); + check!(check!(File::open(&f)).read(&mut mem)); + let read_str = str::from_utf8(&mem).unwrap(); + let expected = format!("{}{}", prefix, n.to_str().unwrap()); + assert_eq!(expected, read_str); + } + check!(fs::remove_file(&f)); + } + check!(fs::remove_dir(dir)); +} + +#[test] +fn file_create_new_already_exists_error() { + let tmpdir = tmpdir(); + let file = &tmpdir.join("file_create_new_error_exists"); + check!(fs::File::create(file)); + let e = fs::OpenOptions::new().write(true).create_new(true).open(file).unwrap_err(); + assert_eq!(e.kind(), ErrorKind::AlreadyExists); +} + +#[test] +fn mkdir_path_already_exists_error() { + let tmpdir = tmpdir(); + let dir = &tmpdir.join("mkdir_error_twice"); + check!(fs::create_dir(dir)); + let e = fs::create_dir(dir).unwrap_err(); + assert_eq!(e.kind(), ErrorKind::AlreadyExists); +} + +#[test] +fn recursive_mkdir() { + let tmpdir = tmpdir(); + let dir = tmpdir.join("d1/d2"); + check!(fs::create_dir_all(&dir)); + assert!(dir.is_dir()) +} + +#[test] +fn recursive_mkdir_failure() { + let tmpdir = tmpdir(); + let dir = tmpdir.join("d1"); + let file = dir.join("f1"); + + check!(fs::create_dir_all(&dir)); + check!(File::create(&file)); + + let result = fs::create_dir_all(&file); + + assert!(result.is_err()); +} + +#[test] +fn concurrent_recursive_mkdir() { + for _ in 0..100 { + let dir = tmpdir(); + let mut dir = dir.join("a"); + for _ in 0..40 { + dir = dir.join("a"); + } + let mut join = vec![]; + for _ in 0..8 { + let dir = dir.clone(); + join.push(thread::spawn(move || { + check!(fs::create_dir_all(&dir)); + })) + } + + // No `Display` on result of `join()` + join.drain(..).map(|join| join.join().unwrap()).count(); + } +} + +#[test] +fn recursive_mkdir_slash() { + check!(fs::create_dir_all(Path::new("/"))); +} + +#[test] +fn recursive_mkdir_dot() { + check!(fs::create_dir_all(Path::new("."))); +} + +#[test] +fn recursive_mkdir_empty() { + check!(fs::create_dir_all(Path::new(""))); +} + +#[test] +fn recursive_rmdir() { + let tmpdir = tmpdir(); + let d1 = tmpdir.join("d1"); + let dt = d1.join("t"); + let dtt = dt.join("t"); + let d2 = tmpdir.join("d2"); + let canary = d2.join("do_not_delete"); + check!(fs::create_dir_all(&dtt)); + check!(fs::create_dir_all(&d2)); + check!(check!(File::create(&canary)).write(b"foo")); + check!(symlink_junction(&d2, &dt.join("d2"))); + let _ = symlink_file(&canary, &d1.join("canary")); + check!(fs::remove_dir_all(&d1)); + + assert!(!d1.is_dir()); + assert!(canary.exists()); +} + +#[test] +fn recursive_rmdir_of_symlink() { + // test we do not recursively delete a symlink but only dirs. + let tmpdir = tmpdir(); + let link = tmpdir.join("d1"); + let dir = tmpdir.join("d2"); + let canary = dir.join("do_not_delete"); + check!(fs::create_dir_all(&dir)); + check!(check!(File::create(&canary)).write(b"foo")); + check!(symlink_junction(&dir, &link)); + check!(fs::remove_dir_all(&link)); + + assert!(!link.is_dir()); + assert!(canary.exists()); +} + +#[test] +// only Windows makes a distinction between file and directory symlinks. +#[cfg(windows)] +fn recursive_rmdir_of_file_symlink() { + let tmpdir = tmpdir(); + if !got_symlink_permission(&tmpdir) { + return; + }; + + let f1 = tmpdir.join("f1"); + let f2 = tmpdir.join("f2"); + check!(check!(File::create(&f1)).write(b"foo")); + check!(symlink_file(&f1, &f2)); + match fs::remove_dir_all(&f2) { + Ok(..) => panic!("wanted a failure"), + Err(..) => {} + } +} + +#[test] +fn unicode_path_is_dir() { + assert!(Path::new(".").is_dir()); + assert!(!Path::new("test/stdtest/fs.rs").is_dir()); + + let tmpdir = tmpdir(); + + let mut dirpath = tmpdir.path().to_path_buf(); + dirpath.push("test-가一ー你好"); + check!(fs::create_dir(&dirpath)); + assert!(dirpath.is_dir()); + + let mut filepath = dirpath; + filepath.push("unicode-file-\u{ac00}\u{4e00}\u{30fc}\u{4f60}\u{597d}.rs"); + check!(File::create(&filepath)); // ignore return; touch only + assert!(!filepath.is_dir()); + assert!(filepath.exists()); +} + +#[test] +fn unicode_path_exists() { + assert!(Path::new(".").exists()); + assert!(!Path::new("test/nonexistent-bogus-path").exists()); + + let tmpdir = tmpdir(); + let unicode = tmpdir.path(); + let unicode = unicode.join("test-각丁ー再见"); + check!(fs::create_dir(&unicode)); + assert!(unicode.exists()); + assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists()); +} + +#[test] +fn copy_file_does_not_exist() { + let from = Path::new("test/nonexistent-bogus-path"); + let to = Path::new("test/other-bogus-path"); + + match fs::copy(&from, &to) { + Ok(..) => panic!(), + Err(..) => { + assert!(!from.exists()); + assert!(!to.exists()); + } + } +} + +#[test] +fn copy_src_does_not_exist() { + let tmpdir = tmpdir(); + let from = Path::new("test/nonexistent-bogus-path"); + let to = tmpdir.join("out.txt"); + check!(check!(File::create(&to)).write(b"hello")); + assert!(fs::copy(&from, &to).is_err()); + assert!(!from.exists()); + let mut v = Vec::new(); + check!(check!(File::open(&to)).read_to_end(&mut v)); + assert_eq!(v, b"hello"); +} + +#[test] +fn copy_file_ok() { + let tmpdir = tmpdir(); + let input = tmpdir.join("in.txt"); + let out = tmpdir.join("out.txt"); + + check!(check!(File::create(&input)).write(b"hello")); + check!(fs::copy(&input, &out)); + let mut v = Vec::new(); + check!(check!(File::open(&out)).read_to_end(&mut v)); + assert_eq!(v, b"hello"); + + assert_eq!(check!(input.metadata()).permissions(), check!(out.metadata()).permissions()); +} + +#[test] +fn copy_file_dst_dir() { + let tmpdir = tmpdir(); + let out = tmpdir.join("out"); + + check!(File::create(&out)); + match fs::copy(&*out, tmpdir.path()) { + Ok(..) => panic!(), + Err(..) => {} + } +} + +#[test] +fn copy_file_dst_exists() { + let tmpdir = tmpdir(); + let input = tmpdir.join("in"); + let output = tmpdir.join("out"); + + check!(check!(File::create(&input)).write("foo".as_bytes())); + check!(check!(File::create(&output)).write("bar".as_bytes())); + check!(fs::copy(&input, &output)); + + let mut v = Vec::new(); + check!(check!(File::open(&output)).read_to_end(&mut v)); + assert_eq!(v, b"foo".to_vec()); +} + +#[test] +fn copy_file_src_dir() { + let tmpdir = tmpdir(); + let out = tmpdir.join("out"); + + match fs::copy(tmpdir.path(), &out) { + Ok(..) => panic!(), + Err(..) => {} + } + assert!(!out.exists()); +} + +#[test] +fn copy_file_preserves_perm_bits() { + let tmpdir = tmpdir(); + let input = tmpdir.join("in.txt"); + let out = tmpdir.join("out.txt"); + + let attr = check!(check!(File::create(&input)).metadata()); + let mut p = attr.permissions(); + p.set_readonly(true); + check!(fs::set_permissions(&input, p)); + check!(fs::copy(&input, &out)); + assert!(check!(out.metadata()).permissions().readonly()); + check!(fs::set_permissions(&input, attr.permissions())); + check!(fs::set_permissions(&out, attr.permissions())); +} + +#[test] +#[cfg(windows)] +fn copy_file_preserves_streams() { + let tmp = tmpdir(); + check!(check!(File::create(tmp.join("in.txt:bunny"))).write("carrot".as_bytes())); + assert_eq!(check!(fs::copy(tmp.join("in.txt"), tmp.join("out.txt"))), 0); + assert_eq!(check!(tmp.join("out.txt").metadata()).len(), 0); + let mut v = Vec::new(); + check!(check!(File::open(tmp.join("out.txt:bunny"))).read_to_end(&mut v)); + assert_eq!(v, b"carrot".to_vec()); +} + +#[test] +fn copy_file_returns_metadata_len() { + let tmp = tmpdir(); + let in_path = tmp.join("in.txt"); + let out_path = tmp.join("out.txt"); + check!(check!(File::create(&in_path)).write(b"lettuce")); + #[cfg(windows)] + check!(check!(File::create(tmp.join("in.txt:bunny"))).write(b"carrot")); + let copied_len = check!(fs::copy(&in_path, &out_path)); + assert_eq!(check!(out_path.metadata()).len(), copied_len); +} + +#[test] +fn copy_file_follows_dst_symlink() { + let tmp = tmpdir(); + if !got_symlink_permission(&tmp) { + return; + }; + + let in_path = tmp.join("in.txt"); + let out_path = tmp.join("out.txt"); + let out_path_symlink = tmp.join("out_symlink.txt"); + + check!(fs::write(&in_path, "foo")); + check!(fs::write(&out_path, "bar")); + check!(symlink_file(&out_path, &out_path_symlink)); + + check!(fs::copy(&in_path, &out_path_symlink)); + + assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink()); + assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec()); + assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec()); +} + +#[test] +fn symlinks_work() { + let tmpdir = tmpdir(); + if !got_symlink_permission(&tmpdir) { + return; + }; + + let input = tmpdir.join("in.txt"); + let out = tmpdir.join("out.txt"); + + check!(check!(File::create(&input)).write("foobar".as_bytes())); + check!(symlink_file(&input, &out)); + assert!(check!(out.symlink_metadata()).file_type().is_symlink()); + assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len()); + let mut v = Vec::new(); + check!(check!(File::open(&out)).read_to_end(&mut v)); + assert_eq!(v, b"foobar".to_vec()); +} + +#[test] +fn symlink_noexist() { + // Symlinks can point to things that don't exist + let tmpdir = tmpdir(); + if !got_symlink_permission(&tmpdir) { + return; + }; + + // Use a relative path for testing. Symlinks get normalized by Windows, + // so we may not get the same path back for absolute paths + check!(symlink_file(&"foo", &tmpdir.join("bar"))); + assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))).to_str().unwrap(), "foo"); +} + +#[test] +fn read_link() { + if cfg!(windows) { + // directory symlink + assert_eq!( + check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(), + r"C:\ProgramData" + ); + // junction + assert_eq!( + check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(), + r"C:\Users\Default" + ); + // junction with special permissions + assert_eq!( + check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(), + r"C:\Users" + ); + } + let tmpdir = tmpdir(); + let link = tmpdir.join("link"); + if !got_symlink_permission(&tmpdir) { + return; + }; + check!(symlink_file(&"foo", &link)); + assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo"); +} + +#[test] +fn readlink_not_symlink() { + let tmpdir = tmpdir(); + match fs::read_link(tmpdir.path()) { + Ok(..) => panic!("wanted a failure"), + Err(..) => {} + } +} + +#[test] +fn links_work() { + let tmpdir = tmpdir(); + let input = tmpdir.join("in.txt"); + let out = tmpdir.join("out.txt"); + + check!(check!(File::create(&input)).write("foobar".as_bytes())); + check!(fs::hard_link(&input, &out)); + assert_eq!(check!(fs::metadata(&out)).len(), check!(fs::metadata(&input)).len()); + assert_eq!(check!(fs::metadata(&out)).len(), check!(input.metadata()).len()); + let mut v = Vec::new(); + check!(check!(File::open(&out)).read_to_end(&mut v)); + assert_eq!(v, b"foobar".to_vec()); + + // can't link to yourself + match fs::hard_link(&input, &input) { + Ok(..) => panic!("wanted a failure"), + Err(..) => {} + } + // can't link to something that doesn't exist + match fs::hard_link(&tmpdir.join("foo"), &tmpdir.join("bar")) { + Ok(..) => panic!("wanted a failure"), + Err(..) => {} + } +} + +#[test] +fn chmod_works() { + let tmpdir = tmpdir(); + let file = tmpdir.join("in.txt"); + + check!(File::create(&file)); + let attr = check!(fs::metadata(&file)); + assert!(!attr.permissions().readonly()); + let mut p = attr.permissions(); + p.set_readonly(true); + check!(fs::set_permissions(&file, p.clone())); + let attr = check!(fs::metadata(&file)); + assert!(attr.permissions().readonly()); + + match fs::set_permissions(&tmpdir.join("foo"), p.clone()) { + Ok(..) => panic!("wanted an error"), + Err(..) => {} + } + + p.set_readonly(false); + check!(fs::set_permissions(&file, p)); +} + +#[test] +fn fchmod_works() { + let tmpdir = tmpdir(); + let path = tmpdir.join("in.txt"); + + let file = check!(File::create(&path)); + let attr = check!(fs::metadata(&path)); + assert!(!attr.permissions().readonly()); + let mut p = attr.permissions(); + p.set_readonly(true); + check!(file.set_permissions(p.clone())); + let attr = check!(fs::metadata(&path)); + assert!(attr.permissions().readonly()); + + p.set_readonly(false); + check!(file.set_permissions(p)); +} + +#[test] +fn sync_doesnt_kill_anything() { + let tmpdir = tmpdir(); + let path = tmpdir.join("in.txt"); + + let mut file = check!(File::create(&path)); + check!(file.sync_all()); + check!(file.sync_data()); + check!(file.write(b"foo")); + check!(file.sync_all()); + check!(file.sync_data()); +} + +#[test] +fn truncate_works() { + let tmpdir = tmpdir(); + let path = tmpdir.join("in.txt"); + + let mut file = check!(File::create(&path)); + check!(file.write(b"foo")); + check!(file.sync_all()); + + // Do some simple things with truncation + assert_eq!(check!(file.metadata()).len(), 3); + check!(file.set_len(10)); + assert_eq!(check!(file.metadata()).len(), 10); + check!(file.write(b"bar")); + check!(file.sync_all()); + assert_eq!(check!(file.metadata()).len(), 10); + + let mut v = Vec::new(); + check!(check!(File::open(&path)).read_to_end(&mut v)); + assert_eq!(v, b"foobar\0\0\0\0".to_vec()); + + // Truncate to a smaller length, don't seek, and then write something. + // Ensure that the intermediate zeroes are all filled in (we have `seek`ed + // past the end of the file). + check!(file.set_len(2)); + assert_eq!(check!(file.metadata()).len(), 2); + check!(file.write(b"wut")); + check!(file.sync_all()); + assert_eq!(check!(file.metadata()).len(), 9); + let mut v = Vec::new(); + check!(check!(File::open(&path)).read_to_end(&mut v)); + assert_eq!(v, b"fo\0\0\0\0wut".to_vec()); +} + +#[test] +fn open_flavors() { + use crate::fs::OpenOptions as OO; + fn c<T: Clone>(t: &T) -> T { + t.clone() + } + + let tmpdir = tmpdir(); + + let mut r = OO::new(); + r.read(true); + let mut w = OO::new(); + w.write(true); + let mut rw = OO::new(); + rw.read(true).write(true); + let mut a = OO::new(); + a.append(true); + let mut ra = OO::new(); + ra.read(true).append(true); + + #[cfg(windows)] + let invalid_options = 87; // ERROR_INVALID_PARAMETER + #[cfg(all(unix, not(target_os = "vxworks")))] + let invalid_options = "Invalid argument"; + #[cfg(target_os = "vxworks")] + let invalid_options = "invalid argument"; + + // Test various combinations of creation modes and access modes. + // + // Allowed: + // creation mode | read | write | read-write | append | read-append | + // :-----------------------|:-----:|:-----:|:----------:|:------:|:-----------:| + // not set (open existing) | X | X | X | X | X | + // create | | X | X | X | X | + // truncate | | X | X | | | + // create and truncate | | X | X | | | + // create_new | | X | X | X | X | + // + // tested in reverse order, so 'create_new' creates the file, and 'open existing' opens it. + + // write-only + check!(c(&w).create_new(true).open(&tmpdir.join("a"))); + check!(c(&w).create(true).truncate(true).open(&tmpdir.join("a"))); + check!(c(&w).truncate(true).open(&tmpdir.join("a"))); + check!(c(&w).create(true).open(&tmpdir.join("a"))); + check!(c(&w).open(&tmpdir.join("a"))); + + // read-only + error!(c(&r).create_new(true).open(&tmpdir.join("b")), invalid_options); + error!(c(&r).create(true).truncate(true).open(&tmpdir.join("b")), invalid_options); + error!(c(&r).truncate(true).open(&tmpdir.join("b")), invalid_options); + error!(c(&r).create(true).open(&tmpdir.join("b")), invalid_options); + check!(c(&r).open(&tmpdir.join("a"))); // try opening the file created with write_only + + // read-write + check!(c(&rw).create_new(true).open(&tmpdir.join("c"))); + check!(c(&rw).create(true).truncate(true).open(&tmpdir.join("c"))); + check!(c(&rw).truncate(true).open(&tmpdir.join("c"))); + check!(c(&rw).create(true).open(&tmpdir.join("c"))); + check!(c(&rw).open(&tmpdir.join("c"))); + + // append + check!(c(&a).create_new(true).open(&tmpdir.join("d"))); + error!(c(&a).create(true).truncate(true).open(&tmpdir.join("d")), invalid_options); + error!(c(&a).truncate(true).open(&tmpdir.join("d")), invalid_options); + check!(c(&a).create(true).open(&tmpdir.join("d"))); + check!(c(&a).open(&tmpdir.join("d"))); + + // read-append + check!(c(&ra).create_new(true).open(&tmpdir.join("e"))); + error!(c(&ra).create(true).truncate(true).open(&tmpdir.join("e")), invalid_options); + error!(c(&ra).truncate(true).open(&tmpdir.join("e")), invalid_options); + check!(c(&ra).create(true).open(&tmpdir.join("e"))); + check!(c(&ra).open(&tmpdir.join("e"))); + + // Test opening a file without setting an access mode + let mut blank = OO::new(); + error!(blank.create(true).open(&tmpdir.join("f")), invalid_options); + + // Test write works + check!(check!(File::create(&tmpdir.join("h"))).write("foobar".as_bytes())); + + // Test write fails for read-only + check!(r.open(&tmpdir.join("h"))); + { + let mut f = check!(r.open(&tmpdir.join("h"))); + assert!(f.write("wut".as_bytes()).is_err()); + } + + // Test write overwrites + { + let mut f = check!(c(&w).open(&tmpdir.join("h"))); + check!(f.write("baz".as_bytes())); + } + { + let mut f = check!(c(&r).open(&tmpdir.join("h"))); + let mut b = vec![0; 6]; + check!(f.read(&mut b)); + assert_eq!(b, "bazbar".as_bytes()); + } + + // Test truncate works + { + let mut f = check!(c(&w).truncate(true).open(&tmpdir.join("h"))); + check!(f.write("foo".as_bytes())); + } + assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3); + + // Test append works + assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 3); + { + let mut f = check!(c(&a).open(&tmpdir.join("h"))); + check!(f.write("bar".as_bytes())); + } + assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 6); + + // Test .append(true) equals .write(true).append(true) + { + let mut f = check!(c(&w).append(true).open(&tmpdir.join("h"))); + check!(f.write("baz".as_bytes())); + } + assert_eq!(check!(fs::metadata(&tmpdir.join("h"))).len(), 9); +} + +#[test] +fn _assert_send_sync() { + fn _assert_send_sync<T: Send + Sync>() {} + _assert_send_sync::<OpenOptions>(); +} + +#[test] +fn binary_file() { + let mut bytes = [0; 1024]; + StdRng::from_entropy().fill_bytes(&mut bytes); + + let tmpdir = tmpdir(); + + check!(check!(File::create(&tmpdir.join("test"))).write(&bytes)); + let mut v = Vec::new(); + check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v)); + assert!(v == &bytes[..]); +} + +#[test] +fn write_then_read() { + let mut bytes = [0; 1024]; + StdRng::from_entropy().fill_bytes(&mut bytes); + + let tmpdir = tmpdir(); + + check!(fs::write(&tmpdir.join("test"), &bytes[..])); + let v = check!(fs::read(&tmpdir.join("test"))); + assert!(v == &bytes[..]); + + check!(fs::write(&tmpdir.join("not-utf8"), &[0xFF])); + error_contains!( + fs::read_to_string(&tmpdir.join("not-utf8")), + "stream did not contain valid UTF-8" + ); + + let s = "𐁁𐀓𐀠𐀴𐀍"; + check!(fs::write(&tmpdir.join("utf8"), s.as_bytes())); + let string = check!(fs::read_to_string(&tmpdir.join("utf8"))); + assert_eq!(string, s); +} + +#[test] +fn file_try_clone() { + let tmpdir = tmpdir(); + + let mut f1 = + check!(OpenOptions::new().read(true).write(true).create(true).open(&tmpdir.join("test"))); + let mut f2 = check!(f1.try_clone()); + + check!(f1.write_all(b"hello world")); + check!(f1.seek(SeekFrom::Start(2))); + + let mut buf = vec![]; + check!(f2.read_to_end(&mut buf)); + assert_eq!(buf, b"llo world"); + drop(f2); + + check!(f1.write_all(b"!")); +} + +#[test] +#[cfg(not(windows))] +fn unlink_readonly() { + let tmpdir = tmpdir(); + let path = tmpdir.join("file"); + check!(File::create(&path)); + let mut perm = check!(fs::metadata(&path)).permissions(); + perm.set_readonly(true); + check!(fs::set_permissions(&path, perm)); + check!(fs::remove_file(&path)); +} + +#[test] +fn mkdir_trailing_slash() { + let tmpdir = tmpdir(); + let path = tmpdir.join("file"); + check!(fs::create_dir_all(&path.join("a/"))); +} + +#[test] +fn canonicalize_works_simple() { + let tmpdir = tmpdir(); + let tmpdir = fs::canonicalize(tmpdir.path()).unwrap(); + let file = tmpdir.join("test"); + File::create(&file).unwrap(); + assert_eq!(fs::canonicalize(&file).unwrap(), file); +} + +#[test] +fn realpath_works() { + let tmpdir = tmpdir(); + if !got_symlink_permission(&tmpdir) { + return; + }; + + let tmpdir = fs::canonicalize(tmpdir.path()).unwrap(); + let file = tmpdir.join("test"); + let dir = tmpdir.join("test2"); + let link = dir.join("link"); + let linkdir = tmpdir.join("test3"); + + File::create(&file).unwrap(); + fs::create_dir(&dir).unwrap(); + symlink_file(&file, &link).unwrap(); + symlink_dir(&dir, &linkdir).unwrap(); + + assert!(link.symlink_metadata().unwrap().file_type().is_symlink()); + + assert_eq!(fs::canonicalize(&tmpdir).unwrap(), tmpdir); + assert_eq!(fs::canonicalize(&file).unwrap(), file); + assert_eq!(fs::canonicalize(&link).unwrap(), file); + assert_eq!(fs::canonicalize(&linkdir).unwrap(), dir); + assert_eq!(fs::canonicalize(&linkdir.join("link")).unwrap(), file); +} + +#[test] +fn realpath_works_tricky() { + let tmpdir = tmpdir(); + if !got_symlink_permission(&tmpdir) { + return; + }; + + let tmpdir = fs::canonicalize(tmpdir.path()).unwrap(); + let a = tmpdir.join("a"); + let b = a.join("b"); + let c = b.join("c"); + let d = a.join("d"); + let e = d.join("e"); + let f = a.join("f"); + + fs::create_dir_all(&b).unwrap(); + fs::create_dir_all(&d).unwrap(); + File::create(&f).unwrap(); + if cfg!(not(windows)) { + symlink_file("../d/e", &c).unwrap(); + symlink_file("../f", &e).unwrap(); + } + if cfg!(windows) { + symlink_file(r"..\d\e", &c).unwrap(); + symlink_file(r"..\f", &e).unwrap(); + } + + assert_eq!(fs::canonicalize(&c).unwrap(), f); + assert_eq!(fs::canonicalize(&e).unwrap(), f); +} + +#[test] +fn dir_entry_methods() { + let tmpdir = tmpdir(); + + fs::create_dir_all(&tmpdir.join("a")).unwrap(); + File::create(&tmpdir.join("b")).unwrap(); + + for file in tmpdir.path().read_dir().unwrap().map(|f| f.unwrap()) { + let fname = file.file_name(); + match fname.to_str() { + Some("a") => { + assert!(file.file_type().unwrap().is_dir()); + assert!(file.metadata().unwrap().is_dir()); + } + Some("b") => { + assert!(file.file_type().unwrap().is_file()); + assert!(file.metadata().unwrap().is_file()); + } + f => panic!("unknown file name: {:?}", f), + } + } +} + +#[test] +fn dir_entry_debug() { + let tmpdir = tmpdir(); + File::create(&tmpdir.join("b")).unwrap(); + let mut read_dir = tmpdir.path().read_dir().unwrap(); + let dir_entry = read_dir.next().unwrap().unwrap(); + let actual = format!("{:?}", dir_entry); + let expected = format!("DirEntry({:?})", dir_entry.0.path()); + assert_eq!(actual, expected); +} + +#[test] +fn read_dir_not_found() { + let res = fs::read_dir("/path/that/does/not/exist"); + assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound); +} + +#[test] +fn create_dir_all_with_junctions() { + let tmpdir = tmpdir(); + let target = tmpdir.join("target"); + + let junction = tmpdir.join("junction"); + let b = junction.join("a/b"); + + let link = tmpdir.join("link"); + let d = link.join("c/d"); + + fs::create_dir(&target).unwrap(); + + check!(symlink_junction(&target, &junction)); + check!(fs::create_dir_all(&b)); + // the junction itself is not a directory, but `is_dir()` on a Path + // follows links + assert!(junction.is_dir()); + assert!(b.exists()); + + if !got_symlink_permission(&tmpdir) { + return; + }; + check!(symlink_dir(&target, &link)); + check!(fs::create_dir_all(&d)); + assert!(link.is_dir()); + assert!(d.exists()); +} + +#[test] +fn metadata_access_times() { + let tmpdir = tmpdir(); + + let b = tmpdir.join("b"); + File::create(&b).unwrap(); + + let a = check!(fs::metadata(&tmpdir.path())); + let b = check!(fs::metadata(&b)); + + assert_eq!(check!(a.accessed()), check!(a.accessed())); + assert_eq!(check!(a.modified()), check!(a.modified())); + assert_eq!(check!(b.accessed()), check!(b.modified())); + + if cfg!(target_os = "macos") || cfg!(target_os = "windows") { + check!(a.created()); + check!(b.created()); + } + + if cfg!(target_os = "linux") { + // Not always available + match (a.created(), b.created()) { + (Ok(t1), Ok(t2)) => assert!(t1 <= t2), + (Err(e1), Err(e2)) + if e1.kind() == ErrorKind::Other && e2.kind() == ErrorKind::Other => {} + (a, b) => { + panic!("creation time must be always supported or not supported: {:?} {:?}", a, b,) + } + } + } +} diff --git a/library/std/src/io/buffered.rs b/library/std/src/io/buffered.rs index ec3c69dd616..5ad8f8132e4 100644 --- a/library/std/src/io/buffered.rs +++ b/library/std/src/io/buffered.rs @@ -1,5 +1,8 @@ //! Buffering wrappers for I/O traits +#[cfg(test)] +mod tests; + use crate::io::prelude::*; use crate::cmp; @@ -1388,923 +1391,3 @@ where .finish() } } - -#[cfg(test)] -mod tests { - use crate::io::prelude::*; - use crate::io::{self, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom}; - use crate::sync::atomic::{AtomicUsize, Ordering}; - use crate::thread; - - /// A dummy reader intended at testing short-reads propagation. - pub struct ShortReader { - lengths: Vec<usize>, - } - - // FIXME: rustfmt and tidy disagree about the correct formatting of this - // function. This leads to issues for users with editors configured to - // rustfmt-on-save. - impl Read for ShortReader { - fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { - if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) } - } - } - - #[test] - fn test_buffered_reader() { - let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; - let mut reader = BufReader::with_capacity(2, inner); - - let mut buf = [0, 0, 0]; - let nread = reader.read(&mut buf); - assert_eq!(nread.unwrap(), 3); - assert_eq!(buf, [5, 6, 7]); - assert_eq!(reader.buffer(), []); - - let mut buf = [0, 0]; - let nread = reader.read(&mut buf); - assert_eq!(nread.unwrap(), 2); - assert_eq!(buf, [0, 1]); - assert_eq!(reader.buffer(), []); - - let mut buf = [0]; - let nread = reader.read(&mut buf); - assert_eq!(nread.unwrap(), 1); - assert_eq!(buf, [2]); - assert_eq!(reader.buffer(), [3]); - - let mut buf = [0, 0, 0]; - let nread = reader.read(&mut buf); - assert_eq!(nread.unwrap(), 1); - assert_eq!(buf, [3, 0, 0]); - assert_eq!(reader.buffer(), []); - - let nread = reader.read(&mut buf); - assert_eq!(nread.unwrap(), 1); - assert_eq!(buf, [4, 0, 0]); - assert_eq!(reader.buffer(), []); - - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn test_buffered_reader_seek() { - let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; - let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner)); - - assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3)); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); - assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3)); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); - assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4)); - assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..])); - reader.consume(1); - assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3)); - } - - #[test] - fn test_buffered_reader_seek_relative() { - let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; - let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner)); - - assert!(reader.seek_relative(3).is_ok()); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); - assert!(reader.seek_relative(0).is_ok()); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); - assert!(reader.seek_relative(1).is_ok()); - assert_eq!(reader.fill_buf().ok(), Some(&[1][..])); - assert!(reader.seek_relative(-1).is_ok()); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); - assert!(reader.seek_relative(2).is_ok()); - assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..])); - } - - #[test] - fn test_buffered_reader_invalidated_after_read() { - let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; - let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner)); - - assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..])); - reader.consume(3); - - let mut buffer = [0, 0, 0, 0, 0]; - assert_eq!(reader.read(&mut buffer).ok(), Some(5)); - assert_eq!(buffer, [0, 1, 2, 3, 4]); - - assert!(reader.seek_relative(-2).is_ok()); - let mut buffer = [0, 0]; - assert_eq!(reader.read(&mut buffer).ok(), Some(2)); - assert_eq!(buffer, [3, 4]); - } - - #[test] - fn test_buffered_reader_invalidated_after_seek() { - let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; - let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner)); - - assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..])); - reader.consume(3); - - assert!(reader.seek(SeekFrom::Current(5)).is_ok()); - - assert!(reader.seek_relative(-2).is_ok()); - let mut buffer = [0, 0]; - assert_eq!(reader.read(&mut buffer).ok(), Some(2)); - assert_eq!(buffer, [3, 4]); - } - - #[test] - fn test_buffered_reader_seek_underflow() { - // gimmick reader that yields its position modulo 256 for each byte - struct PositionReader { - pos: u64, - } - impl Read for PositionReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - let len = buf.len(); - for x in buf { - *x = self.pos as u8; - self.pos = self.pos.wrapping_add(1); - } - Ok(len) - } - } - impl Seek for PositionReader { - fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { - match pos { - SeekFrom::Start(n) => { - self.pos = n; - } - SeekFrom::Current(n) => { - self.pos = self.pos.wrapping_add(n as u64); - } - SeekFrom::End(n) => { - self.pos = u64::MAX.wrapping_add(n as u64); - } - } - Ok(self.pos) - } - } - - let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 }); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..])); - assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5)); - assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); - // the following seek will require two underlying seeks - let expected = 9223372036854775802; - assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected)); - assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); - // seeking to 0 should empty the buffer. - assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected)); - assert_eq!(reader.get_ref().pos, expected); - } - - #[test] - fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() { - // gimmick reader that returns Err after first seek - struct ErrAfterFirstSeekReader { - first_seek: bool, - } - impl Read for ErrAfterFirstSeekReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - for x in &mut *buf { - *x = 0; - } - Ok(buf.len()) - } - } - impl Seek for ErrAfterFirstSeekReader { - fn seek(&mut self, _: SeekFrom) -> io::Result<u64> { - if self.first_seek { - self.first_seek = false; - Ok(0) - } else { - Err(io::Error::new(io::ErrorKind::Other, "oh no!")) - } - } - } - - let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true }); - assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..])); - - // The following seek will require two underlying seeks. The first will - // succeed but the second will fail. This should still invalidate the - // buffer. - assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err()); - assert_eq!(reader.buffer().len(), 0); - } - - #[test] - fn test_buffered_writer() { - let inner = Vec::new(); - let mut writer = BufWriter::with_capacity(2, inner); - - writer.write(&[0, 1]).unwrap(); - assert_eq!(writer.buffer(), []); - assert_eq!(*writer.get_ref(), [0, 1]); - - writer.write(&[2]).unwrap(); - assert_eq!(writer.buffer(), [2]); - assert_eq!(*writer.get_ref(), [0, 1]); - - writer.write(&[3]).unwrap(); - assert_eq!(writer.buffer(), [2, 3]); - assert_eq!(*writer.get_ref(), [0, 1]); - - writer.flush().unwrap(); - assert_eq!(writer.buffer(), []); - assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); - - writer.write(&[4]).unwrap(); - writer.write(&[5]).unwrap(); - assert_eq!(writer.buffer(), [4, 5]); - assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); - - writer.write(&[6]).unwrap(); - assert_eq!(writer.buffer(), [6]); - assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]); - - writer.write(&[7, 8]).unwrap(); - assert_eq!(writer.buffer(), []); - assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]); - - writer.write(&[9, 10, 11]).unwrap(); - assert_eq!(writer.buffer(), []); - assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); - - writer.flush().unwrap(); - assert_eq!(writer.buffer(), []); - assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); - } - - #[test] - fn test_buffered_writer_inner_flushes() { - let mut w = BufWriter::with_capacity(3, Vec::new()); - w.write(&[0, 1]).unwrap(); - assert_eq!(*w.get_ref(), []); - let w = w.into_inner().unwrap(); - assert_eq!(w, [0, 1]); - } - - #[test] - fn test_buffered_writer_seek() { - let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new())); - w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap(); - w.write_all(&[6, 7]).unwrap(); - assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8)); - assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]); - assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2)); - w.write_all(&[8, 9]).unwrap(); - assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]); - } - - #[test] - fn test_read_until() { - let inner: &[u8] = &[0, 1, 2, 1, 0]; - let mut reader = BufReader::with_capacity(2, inner); - let mut v = Vec::new(); - reader.read_until(0, &mut v).unwrap(); - assert_eq!(v, [0]); - v.truncate(0); - reader.read_until(2, &mut v).unwrap(); - assert_eq!(v, [1, 2]); - v.truncate(0); - reader.read_until(1, &mut v).unwrap(); - assert_eq!(v, [1]); - v.truncate(0); - reader.read_until(8, &mut v).unwrap(); - assert_eq!(v, [0]); - v.truncate(0); - reader.read_until(9, &mut v).unwrap(); - assert_eq!(v, []); - } - - #[test] - fn test_line_buffer() { - let mut writer = LineWriter::new(Vec::new()); - writer.write(&[0]).unwrap(); - assert_eq!(*writer.get_ref(), []); - writer.write(&[1]).unwrap(); - assert_eq!(*writer.get_ref(), []); - writer.flush().unwrap(); - assert_eq!(*writer.get_ref(), [0, 1]); - writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap(); - assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']); - writer.flush().unwrap(); - assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]); - writer.write(&[3, b'\n']).unwrap(); - assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']); - } - - #[test] - fn test_read_line() { - let in_buf: &[u8] = b"a\nb\nc"; - let mut reader = BufReader::with_capacity(2, in_buf); - let mut s = String::new(); - reader.read_line(&mut s).unwrap(); - assert_eq!(s, "a\n"); - s.truncate(0); - reader.read_line(&mut s).unwrap(); - assert_eq!(s, "b\n"); - s.truncate(0); - reader.read_line(&mut s).unwrap(); - assert_eq!(s, "c"); - s.truncate(0); - reader.read_line(&mut s).unwrap(); - assert_eq!(s, ""); - } - - #[test] - fn test_lines() { - let in_buf: &[u8] = b"a\nb\nc"; - let reader = BufReader::with_capacity(2, in_buf); - let mut it = reader.lines(); - assert_eq!(it.next().unwrap().unwrap(), "a".to_string()); - assert_eq!(it.next().unwrap().unwrap(), "b".to_string()); - assert_eq!(it.next().unwrap().unwrap(), "c".to_string()); - assert!(it.next().is_none()); - } - - #[test] - fn test_short_reads() { - let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] }; - let mut reader = BufReader::new(inner); - let mut buf = [0, 0]; - assert_eq!(reader.read(&mut buf).unwrap(), 0); - assert_eq!(reader.read(&mut buf).unwrap(), 1); - assert_eq!(reader.read(&mut buf).unwrap(), 2); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - assert_eq!(reader.read(&mut buf).unwrap(), 1); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - #[should_panic] - fn dont_panic_in_drop_on_panicked_flush() { - struct FailFlushWriter; - - impl Write for FailFlushWriter { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - Ok(buf.len()) - } - fn flush(&mut self) -> io::Result<()> { - Err(io::Error::last_os_error()) - } - } - - let writer = FailFlushWriter; - let _writer = BufWriter::new(writer); - - // If writer panics *again* due to the flush error then the process will - // abort. - panic!(); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn panic_in_write_doesnt_flush_in_drop() { - static WRITES: AtomicUsize = AtomicUsize::new(0); - - struct PanicWriter; - - impl Write for PanicWriter { - fn write(&mut self, _: &[u8]) -> io::Result<usize> { - WRITES.fetch_add(1, Ordering::SeqCst); - panic!(); - } - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } - } - - thread::spawn(|| { - let mut writer = BufWriter::new(PanicWriter); - let _ = writer.write(b"hello world"); - let _ = writer.flush(); - }) - .join() - .unwrap_err(); - - assert_eq!(WRITES.load(Ordering::SeqCst), 1); - } - - #[bench] - fn bench_buffered_reader(b: &mut test::Bencher) { - b.iter(|| BufReader::new(io::empty())); - } - - #[bench] - fn bench_buffered_writer(b: &mut test::Bencher) { - b.iter(|| BufWriter::new(io::sink())); - } - - /// A simple `Write` target, designed to be wrapped by `LineWriter` / - /// `BufWriter` / etc, that can have its `write` & `flush` behavior - /// configured - #[derive(Default, Clone)] - struct ProgrammableSink { - // Writes append to this slice - pub buffer: Vec<u8>, - - // Flush sets this flag - pub flushed: bool, - - // If true, writes will always be an error - pub always_write_error: bool, - - // If true, flushes will always be an error - pub always_flush_error: bool, - - // If set, only up to this number of bytes will be written in a single - // call to `write` - pub accept_prefix: Option<usize>, - - // If set, counts down with each write, and writes return an error - // when it hits 0 - pub max_writes: Option<usize>, - - // If set, attempting to write when max_writes == Some(0) will be an - // error; otherwise, it will return Ok(0). - pub error_after_max_writes: bool, - } - - impl Write for ProgrammableSink { - fn write(&mut self, data: &[u8]) -> io::Result<usize> { - if self.always_write_error { - return Err(io::Error::new(io::ErrorKind::Other, "test - always_write_error")); - } - - match self.max_writes { - Some(0) if self.error_after_max_writes => { - return Err(io::Error::new(io::ErrorKind::Other, "test - max_writes")); - } - Some(0) => return Ok(0), - Some(ref mut count) => *count -= 1, - None => {} - } - - let len = match self.accept_prefix { - None => data.len(), - Some(prefix) => data.len().min(prefix), - }; - - let data = &data[..len]; - self.buffer.extend_from_slice(data); - - Ok(len) - } - - fn flush(&mut self) -> io::Result<()> { - if self.always_flush_error { - Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error")) - } else { - self.flushed = true; - Ok(()) - } - } - } - - /// Previously the `LineWriter` could successfully write some bytes but - /// then fail to report that it has done so. Additionally, an erroneous - /// flush after a successful write was permanently ignored. - /// - /// Test that a line writer correctly reports the number of written bytes, - /// and that it attempts to flush buffered lines from previous writes - /// before processing new data - /// - /// Regression test for #37807 - #[test] - fn erroneous_flush_retried() { - let writer = ProgrammableSink { - // Only write up to 4 bytes at a time - accept_prefix: Some(4), - - // Accept the first two writes, then error the others - max_writes: Some(2), - error_after_max_writes: true, - - ..Default::default() - }; - - // This should write the first 4 bytes. The rest will be buffered, out - // to the last newline. - let mut writer = LineWriter::new(writer); - assert_eq!(writer.write(b"a\nb\nc\nd\ne").unwrap(), 8); - - // This write should attempt to flush "c\nd\n", then buffer "e". No - // errors should happen here because no further writes should be - // attempted against `writer`. - assert_eq!(writer.write(b"e").unwrap(), 1); - assert_eq!(&writer.get_ref().buffer, b"a\nb\nc\nd\n"); - } - - #[test] - fn line_vectored() { - let mut a = LineWriter::new(Vec::new()); - assert_eq!( - a.write_vectored(&[ - IoSlice::new(&[]), - IoSlice::new(b"\n"), - IoSlice::new(&[]), - IoSlice::new(b"a"), - ]) - .unwrap(), - 2, - ); - assert_eq!(a.get_ref(), b"\n"); - - assert_eq!( - a.write_vectored(&[ - IoSlice::new(&[]), - IoSlice::new(b"b"), - IoSlice::new(&[]), - IoSlice::new(b"a"), - IoSlice::new(&[]), - IoSlice::new(b"c"), - ]) - .unwrap(), - 3, - ); - assert_eq!(a.get_ref(), b"\n"); - a.flush().unwrap(); - assert_eq!(a.get_ref(), b"\nabac"); - assert_eq!(a.write_vectored(&[]).unwrap(), 0); - assert_eq!( - a.write_vectored(&[ - IoSlice::new(&[]), - IoSlice::new(&[]), - IoSlice::new(&[]), - IoSlice::new(&[]), - ]) - .unwrap(), - 0, - ); - assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3); - assert_eq!(a.get_ref(), b"\nabaca\nb"); - } - - #[test] - fn line_vectored_partial_and_errors() { - use crate::collections::VecDeque; - - enum Call { - Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> }, - Flush { output: io::Result<()> }, - } - - #[derive(Default)] - struct Writer { - calls: VecDeque<Call>, - } - - impl Write for Writer { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.write_vectored(&[IoSlice::new(buf)]) - } - - fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> { - match self.calls.pop_front().expect("unexpected call to write") { - Call::Write { inputs, output } => { - assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>()); - output - } - Call::Flush { .. } => panic!("unexpected call to write; expected a flush"), - } - } - - fn is_write_vectored(&self) -> bool { - true - } - - fn flush(&mut self) -> io::Result<()> { - match self.calls.pop_front().expect("Unexpected call to flush") { - Call::Flush { output } => output, - Call::Write { .. } => panic!("unexpected call to flush; expected a write"), - } - } - } - - impl Drop for Writer { - fn drop(&mut self) { - if !thread::panicking() { - assert_eq!(self.calls.len(), 0); - } - } - } - - // partial writes keep going - let mut a = LineWriter::new(Writer::default()); - a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap(); - - a.get_mut().calls.push_back(Call::Write { inputs: vec![b"abc"], output: Ok(1) }); - a.get_mut().calls.push_back(Call::Write { inputs: vec![b"bc"], output: Ok(2) }); - a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\n"], output: Ok(2) }); - - a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap(); - - a.get_mut().calls.push_back(Call::Flush { output: Ok(()) }); - a.flush().unwrap(); - - // erroneous writes stop and don't write more - a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\na"], output: Err(err()) }); - a.get_mut().calls.push_back(Call::Flush { output: Ok(()) }); - assert!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).is_err()); - a.flush().unwrap(); - - fn err() -> io::Error { - io::Error::new(io::ErrorKind::Other, "x") - } - } - - /// Test that, in cases where vectored writing is not enabled, the - /// LineWriter uses the normal `write` call, which more-correctly handles - /// partial lines - #[test] - fn line_vectored_ignored() { - let writer = ProgrammableSink::default(); - let mut writer = LineWriter::new(writer); - - let content = [ - IoSlice::new(&[]), - IoSlice::new(b"Line 1\nLine"), - IoSlice::new(b" 2\nLine 3\nL"), - IoSlice::new(&[]), - IoSlice::new(&[]), - IoSlice::new(b"ine 4"), - IoSlice::new(b"\nLine 5\n"), - ]; - - let count = writer.write_vectored(&content).unwrap(); - assert_eq!(count, 11); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); - - let count = writer.write_vectored(&content[2..]).unwrap(); - assert_eq!(count, 11); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n"); - - let count = writer.write_vectored(&content[5..]).unwrap(); - assert_eq!(count, 5); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n"); - - let count = writer.write_vectored(&content[6..]).unwrap(); - assert_eq!(count, 8); - assert_eq!( - writer.get_ref().buffer.as_slice(), - b"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n".as_ref() - ); - } - - /// Test that, given this input: - /// - /// Line 1\n - /// Line 2\n - /// Line 3\n - /// Line 4 - /// - /// And given a result that only writes to midway through Line 2 - /// - /// That only up to the end of Line 3 is buffered - /// - /// This behavior is desirable because it prevents flushing partial lines - #[test] - fn partial_write_buffers_line() { - let writer = ProgrammableSink { accept_prefix: Some(13), ..Default::default() }; - let mut writer = LineWriter::new(writer); - - assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3\nLine4").unwrap(), 21); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2"); - - assert_eq!(writer.write(b"Line 4").unwrap(), 6); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n"); - } - - /// Test that, given this input: - /// - /// Line 1\n - /// Line 2\n - /// Line 3 - /// - /// And given that the full write of lines 1 and 2 was successful - /// That data up to Line 3 is buffered - #[test] - fn partial_line_buffered_after_line_write() { - let writer = ProgrammableSink::default(); - let mut writer = LineWriter::new(writer); - - assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3").unwrap(), 20); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\n"); - - assert!(writer.flush().is_ok()); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3"); - } - - /// Test that, given a partial line that exceeds the length of - /// LineBuffer's buffer (that is, without a trailing newline), that that - /// line is written to the inner writer - #[test] - fn long_line_flushed() { - let writer = ProgrammableSink::default(); - let mut writer = LineWriter::with_capacity(5, writer); - - assert_eq!(writer.write(b"0123456789").unwrap(), 10); - assert_eq!(&writer.get_ref().buffer, b"0123456789"); - } - - /// Test that, given a very long partial line *after* successfully - /// flushing a complete line, that that line is buffered unconditionally, - /// and no additional writes take place. This assures the property that - /// `write` should make at-most-one attempt to write new data. - #[test] - fn line_long_tail_not_flushed() { - let writer = ProgrammableSink::default(); - let mut writer = LineWriter::with_capacity(5, writer); - - // Assert that Line 1\n is flushed, and 01234 is buffered - assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); - - // Because the buffer is full, this subsequent write will flush it - assert_eq!(writer.write(b"5").unwrap(), 1); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234"); - } - - /// Test that, if an attempt to pre-flush buffered data returns Ok(0), - /// this is propagated as an error. - #[test] - fn line_buffer_write0_error() { - let writer = ProgrammableSink { - // Accept one write, then return Ok(0) on subsequent ones - max_writes: Some(1), - - ..Default::default() - }; - let mut writer = LineWriter::new(writer); - - // This should write "Line 1\n" and buffer "Partial" - assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); - - // This will attempt to flush "partial", which will return Ok(0), which - // needs to be an error, because we've already informed the client - // that we accepted the write. - let err = writer.write(b" Line End\n").unwrap_err(); - assert_eq!(err.kind(), ErrorKind::WriteZero); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); - } - - /// Test that, if a write returns Ok(0) after a successful pre-flush, this - /// is propagated as Ok(0) - #[test] - fn line_buffer_write0_normal() { - let writer = ProgrammableSink { - // Accept two writes, then return Ok(0) on subsequent ones - max_writes: Some(2), - - ..Default::default() - }; - let mut writer = LineWriter::new(writer); - - // This should write "Line 1\n" and buffer "Partial" - assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); - - // This will flush partial, which will succeed, but then return Ok(0) - // when flushing " Line End\n" - assert_eq!(writer.write(b" Line End\n").unwrap(), 0); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nPartial"); - } - - /// LineWriter has a custom `write_all`; make sure it works correctly - #[test] - fn line_write_all() { - let writer = ProgrammableSink { - // Only write 5 bytes at a time - accept_prefix: Some(5), - ..Default::default() - }; - let mut writer = LineWriter::new(writer); - - writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial").unwrap(); - assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\nLine 4\n"); - writer.write_all(b" Line 5\n").unwrap(); - assert_eq!( - writer.get_ref().buffer.as_slice(), - b"Line 1\nLine 2\nLine 3\nLine 4\nPartial Line 5\n".as_ref(), - ); - } - - #[test] - fn line_write_all_error() { - let writer = ProgrammableSink { - // Only accept up to 3 writes of up to 5 bytes each - accept_prefix: Some(5), - max_writes: Some(3), - ..Default::default() - }; - - let mut writer = LineWriter::new(writer); - let res = writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial"); - assert!(res.is_err()); - // An error from write_all leaves everything in an indeterminate state, - // so there's nothing else to test here - } - - /// Under certain circumstances, the old implementation of LineWriter - /// would try to buffer "to the last newline" but be forced to buffer - /// less than that, leading to inappropriate partial line writes. - /// Regression test for that issue. - #[test] - fn partial_multiline_buffering() { - let writer = ProgrammableSink { - // Write only up to 5 bytes at a time - accept_prefix: Some(5), - ..Default::default() - }; - - let mut writer = LineWriter::with_capacity(10, writer); - - let content = b"AAAAABBBBB\nCCCCDDDDDD\nEEE"; - - // When content is written, LineWriter will try to write blocks A, B, - // C, and D. Only block A will succeed. Under the old behavior, LineWriter - // would then try to buffer B, C and D, but because its capacity is 10, - // it will only be able to buffer B and C. We don't want to buffer - // partial lines concurrent with whole lines, so the correct behavior - // is to buffer only block B (out to the newline) - assert_eq!(writer.write(content).unwrap(), 11); - assert_eq!(writer.get_ref().buffer, *b"AAAAA"); - - writer.flush().unwrap(); - assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB\n"); - } - - /// Same as test_partial_multiline_buffering, but in the event NO full lines - /// fit in the buffer, just buffer as much as possible - #[test] - fn partial_multiline_buffering_without_full_line() { - let writer = ProgrammableSink { - // Write only up to 5 bytes at a time - accept_prefix: Some(5), - ..Default::default() - }; - - let mut writer = LineWriter::with_capacity(5, writer); - - let content = b"AAAAABBBBBBBBBB\nCCCCC\nDDDDD"; - - // When content is written, LineWriter will try to write blocks A, B, - // and C. Only block A will succeed. Under the old behavior, LineWriter - // would then try to buffer B and C, but because its capacity is 5, - // it will only be able to buffer part of B. Because it's not possible - // for it to buffer any complete lines, it should buffer as much of B as - // possible - assert_eq!(writer.write(content).unwrap(), 10); - assert_eq!(writer.get_ref().buffer, *b"AAAAA"); - - writer.flush().unwrap(); - assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB"); - } - - #[derive(Debug, Clone, PartialEq, Eq)] - enum RecordedEvent { - Write(String), - Flush, - } - - #[derive(Debug, Clone, Default)] - struct WriteRecorder { - pub events: Vec<RecordedEvent>, - } - - impl Write for WriteRecorder { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - use crate::str::from_utf8; - - self.events.push(RecordedEvent::Write(from_utf8(buf).unwrap().to_string())); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - self.events.push(RecordedEvent::Flush); - Ok(()) - } - } - - /// Test that a normal, formatted writeln only results in a single write - /// call to the underlying writer. A naive implementation of - /// LineWriter::write_all results in two writes: one of the buffered data, - /// and another of the final substring in the formatted set - #[test] - fn single_formatted_write() { - let writer = WriteRecorder::default(); - let mut writer = LineWriter::new(writer); - - // Under a naive implementation of LineWriter, this will result in two - // writes: "hello, world" and "!\n", because write() has to flush the - // buffer before attempting to write the last "!\n". write_all shouldn't - // have this limitation. - writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap(); - assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]); - } -} diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs new file mode 100644 index 00000000000..1cd02ee299a --- /dev/null +++ b/library/std/src/io/buffered/tests.rs @@ -0,0 +1,916 @@ +use crate::io::prelude::*; +use crate::io::{self, BufReader, BufWriter, ErrorKind, IoSlice, LineWriter, SeekFrom}; +use crate::sync::atomic::{AtomicUsize, Ordering}; +use crate::thread; + +/// A dummy reader intended at testing short-reads propagation. +pub struct ShortReader { + lengths: Vec<usize>, +} + +// FIXME: rustfmt and tidy disagree about the correct formatting of this +// function. This leads to issues for users with editors configured to +// rustfmt-on-save. +impl Read for ShortReader { + fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { + if self.lengths.is_empty() { Ok(0) } else { Ok(self.lengths.remove(0)) } + } +} + +#[test] +fn test_buffered_reader() { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(2, inner); + + let mut buf = [0, 0, 0]; + let nread = reader.read(&mut buf); + assert_eq!(nread.unwrap(), 3); + assert_eq!(buf, [5, 6, 7]); + assert_eq!(reader.buffer(), []); + + let mut buf = [0, 0]; + let nread = reader.read(&mut buf); + assert_eq!(nread.unwrap(), 2); + assert_eq!(buf, [0, 1]); + assert_eq!(reader.buffer(), []); + + let mut buf = [0]; + let nread = reader.read(&mut buf); + assert_eq!(nread.unwrap(), 1); + assert_eq!(buf, [2]); + assert_eq!(reader.buffer(), [3]); + + let mut buf = [0, 0, 0]; + let nread = reader.read(&mut buf); + assert_eq!(nread.unwrap(), 1); + assert_eq!(buf, [3, 0, 0]); + assert_eq!(reader.buffer(), []); + + let nread = reader.read(&mut buf); + assert_eq!(nread.unwrap(), 1); + assert_eq!(buf, [4, 0, 0]); + assert_eq!(reader.buffer(), []); + + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn test_buffered_reader_seek() { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner)); + + assert_eq!(reader.seek(SeekFrom::Start(3)).ok(), Some(3)); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); + assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(3)); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); + assert_eq!(reader.seek(SeekFrom::Current(1)).ok(), Some(4)); + assert_eq!(reader.fill_buf().ok(), Some(&[1, 2][..])); + reader.consume(1); + assert_eq!(reader.seek(SeekFrom::Current(-2)).ok(), Some(3)); +} + +#[test] +fn test_buffered_reader_seek_relative() { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(2, io::Cursor::new(inner)); + + assert!(reader.seek_relative(3).is_ok()); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); + assert!(reader.seek_relative(0).is_ok()); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); + assert!(reader.seek_relative(1).is_ok()); + assert_eq!(reader.fill_buf().ok(), Some(&[1][..])); + assert!(reader.seek_relative(-1).is_ok()); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 1][..])); + assert!(reader.seek_relative(2).is_ok()); + assert_eq!(reader.fill_buf().ok(), Some(&[2, 3][..])); +} + +#[test] +fn test_buffered_reader_invalidated_after_read() { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner)); + + assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..])); + reader.consume(3); + + let mut buffer = [0, 0, 0, 0, 0]; + assert_eq!(reader.read(&mut buffer).ok(), Some(5)); + assert_eq!(buffer, [0, 1, 2, 3, 4]); + + assert!(reader.seek_relative(-2).is_ok()); + let mut buffer = [0, 0]; + assert_eq!(reader.read(&mut buffer).ok(), Some(2)); + assert_eq!(buffer, [3, 4]); +} + +#[test] +fn test_buffered_reader_invalidated_after_seek() { + let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4]; + let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner)); + + assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..])); + reader.consume(3); + + assert!(reader.seek(SeekFrom::Current(5)).is_ok()); + + assert!(reader.seek_relative(-2).is_ok()); + let mut buffer = [0, 0]; + assert_eq!(reader.read(&mut buffer).ok(), Some(2)); + assert_eq!(buffer, [3, 4]); +} + +#[test] +fn test_buffered_reader_seek_underflow() { + // gimmick reader that yields its position modulo 256 for each byte + struct PositionReader { + pos: u64, + } + impl Read for PositionReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + let len = buf.len(); + for x in buf { + *x = self.pos as u8; + self.pos = self.pos.wrapping_add(1); + } + Ok(len) + } + } + impl Seek for PositionReader { + fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { + match pos { + SeekFrom::Start(n) => { + self.pos = n; + } + SeekFrom::Current(n) => { + self.pos = self.pos.wrapping_add(n as u64); + } + SeekFrom::End(n) => { + self.pos = u64::MAX.wrapping_add(n as u64); + } + } + Ok(self.pos) + } + } + + let mut reader = BufReader::with_capacity(5, PositionReader { pos: 0 }); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2, 3, 4][..])); + assert_eq!(reader.seek(SeekFrom::End(-5)).ok(), Some(u64::MAX - 5)); + assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); + // the following seek will require two underlying seeks + let expected = 9223372036854775802; + assert_eq!(reader.seek(SeekFrom::Current(i64::MIN)).ok(), Some(expected)); + assert_eq!(reader.fill_buf().ok().map(|s| s.len()), Some(5)); + // seeking to 0 should empty the buffer. + assert_eq!(reader.seek(SeekFrom::Current(0)).ok(), Some(expected)); + assert_eq!(reader.get_ref().pos, expected); +} + +#[test] +fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() { + // gimmick reader that returns Err after first seek + struct ErrAfterFirstSeekReader { + first_seek: bool, + } + impl Read for ErrAfterFirstSeekReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + for x in &mut *buf { + *x = 0; + } + Ok(buf.len()) + } + } + impl Seek for ErrAfterFirstSeekReader { + fn seek(&mut self, _: SeekFrom) -> io::Result<u64> { + if self.first_seek { + self.first_seek = false; + Ok(0) + } else { + Err(io::Error::new(io::ErrorKind::Other, "oh no!")) + } + } + } + + let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true }); + assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..])); + + // The following seek will require two underlying seeks. The first will + // succeed but the second will fail. This should still invalidate the + // buffer. + assert!(reader.seek(SeekFrom::Current(i64::MIN)).is_err()); + assert_eq!(reader.buffer().len(), 0); +} + +#[test] +fn test_buffered_writer() { + let inner = Vec::new(); + let mut writer = BufWriter::with_capacity(2, inner); + + writer.write(&[0, 1]).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1]); + + writer.write(&[2]).unwrap(); + assert_eq!(writer.buffer(), [2]); + assert_eq!(*writer.get_ref(), [0, 1]); + + writer.write(&[3]).unwrap(); + assert_eq!(writer.buffer(), [2, 3]); + assert_eq!(*writer.get_ref(), [0, 1]); + + writer.flush().unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); + + writer.write(&[4]).unwrap(); + writer.write(&[5]).unwrap(); + assert_eq!(writer.buffer(), [4, 5]); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3]); + + writer.write(&[6]).unwrap(); + assert_eq!(writer.buffer(), [6]); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]); + + writer.write(&[7, 8]).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]); + + writer.write(&[9, 10, 11]).unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); + + writer.flush().unwrap(); + assert_eq!(writer.buffer(), []); + assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); +} + +#[test] +fn test_buffered_writer_inner_flushes() { + let mut w = BufWriter::with_capacity(3, Vec::new()); + w.write(&[0, 1]).unwrap(); + assert_eq!(*w.get_ref(), []); + let w = w.into_inner().unwrap(); + assert_eq!(w, [0, 1]); +} + +#[test] +fn test_buffered_writer_seek() { + let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new())); + w.write_all(&[0, 1, 2, 3, 4, 5]).unwrap(); + w.write_all(&[6, 7]).unwrap(); + assert_eq!(w.seek(SeekFrom::Current(0)).ok(), Some(8)); + assert_eq!(&w.get_ref().get_ref()[..], &[0, 1, 2, 3, 4, 5, 6, 7][..]); + assert_eq!(w.seek(SeekFrom::Start(2)).ok(), Some(2)); + w.write_all(&[8, 9]).unwrap(); + assert_eq!(&w.into_inner().unwrap().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]); +} + +#[test] +fn test_read_until() { + let inner: &[u8] = &[0, 1, 2, 1, 0]; + let mut reader = BufReader::with_capacity(2, inner); + let mut v = Vec::new(); + reader.read_until(0, &mut v).unwrap(); + assert_eq!(v, [0]); + v.truncate(0); + reader.read_until(2, &mut v).unwrap(); + assert_eq!(v, [1, 2]); + v.truncate(0); + reader.read_until(1, &mut v).unwrap(); + assert_eq!(v, [1]); + v.truncate(0); + reader.read_until(8, &mut v).unwrap(); + assert_eq!(v, [0]); + v.truncate(0); + reader.read_until(9, &mut v).unwrap(); + assert_eq!(v, []); +} + +#[test] +fn test_line_buffer() { + let mut writer = LineWriter::new(Vec::new()); + writer.write(&[0]).unwrap(); + assert_eq!(*writer.get_ref(), []); + writer.write(&[1]).unwrap(); + assert_eq!(*writer.get_ref(), []); + writer.flush().unwrap(); + assert_eq!(*writer.get_ref(), [0, 1]); + writer.write(&[0, b'\n', 1, b'\n', 2]).unwrap(); + assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n']); + writer.flush().unwrap(); + assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2]); + writer.write(&[3, b'\n']).unwrap(); + assert_eq!(*writer.get_ref(), [0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n']); +} + +#[test] +fn test_read_line() { + let in_buf: &[u8] = b"a\nb\nc"; + let mut reader = BufReader::with_capacity(2, in_buf); + let mut s = String::new(); + reader.read_line(&mut s).unwrap(); + assert_eq!(s, "a\n"); + s.truncate(0); + reader.read_line(&mut s).unwrap(); + assert_eq!(s, "b\n"); + s.truncate(0); + reader.read_line(&mut s).unwrap(); + assert_eq!(s, "c"); + s.truncate(0); + reader.read_line(&mut s).unwrap(); + assert_eq!(s, ""); +} + +#[test] +fn test_lines() { + let in_buf: &[u8] = b"a\nb\nc"; + let reader = BufReader::with_capacity(2, in_buf); + let mut it = reader.lines(); + assert_eq!(it.next().unwrap().unwrap(), "a".to_string()); + assert_eq!(it.next().unwrap().unwrap(), "b".to_string()); + assert_eq!(it.next().unwrap().unwrap(), "c".to_string()); + assert!(it.next().is_none()); +} + +#[test] +fn test_short_reads() { + let inner = ShortReader { lengths: vec![0, 1, 2, 0, 1, 0] }; + let mut reader = BufReader::new(inner); + let mut buf = [0, 0]; + assert_eq!(reader.read(&mut buf).unwrap(), 0); + assert_eq!(reader.read(&mut buf).unwrap(), 1); + assert_eq!(reader.read(&mut buf).unwrap(), 2); + assert_eq!(reader.read(&mut buf).unwrap(), 0); + assert_eq!(reader.read(&mut buf).unwrap(), 1); + assert_eq!(reader.read(&mut buf).unwrap(), 0); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +#[should_panic] +fn dont_panic_in_drop_on_panicked_flush() { + struct FailFlushWriter; + + impl Write for FailFlushWriter { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + Ok(buf.len()) + } + fn flush(&mut self) -> io::Result<()> { + Err(io::Error::last_os_error()) + } + } + + let writer = FailFlushWriter; + let _writer = BufWriter::new(writer); + + // If writer panics *again* due to the flush error then the process will + // abort. + panic!(); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn panic_in_write_doesnt_flush_in_drop() { + static WRITES: AtomicUsize = AtomicUsize::new(0); + + struct PanicWriter; + + impl Write for PanicWriter { + fn write(&mut self, _: &[u8]) -> io::Result<usize> { + WRITES.fetch_add(1, Ordering::SeqCst); + panic!(); + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + } + + thread::spawn(|| { + let mut writer = BufWriter::new(PanicWriter); + let _ = writer.write(b"hello world"); + let _ = writer.flush(); + }) + .join() + .unwrap_err(); + + assert_eq!(WRITES.load(Ordering::SeqCst), 1); +} + +#[bench] +fn bench_buffered_reader(b: &mut test::Bencher) { + b.iter(|| BufReader::new(io::empty())); +} + +#[bench] +fn bench_buffered_writer(b: &mut test::Bencher) { + b.iter(|| BufWriter::new(io::sink())); +} + +/// A simple `Write` target, designed to be wrapped by `LineWriter` / +/// `BufWriter` / etc, that can have its `write` & `flush` behavior +/// configured +#[derive(Default, Clone)] +struct ProgrammableSink { + // Writes append to this slice + pub buffer: Vec<u8>, + + // Flush sets this flag + pub flushed: bool, + + // If true, writes will always be an error + pub always_write_error: bool, + + // If true, flushes will always be an error + pub always_flush_error: bool, + + // If set, only up to this number of bytes will be written in a single + // call to `write` + pub accept_prefix: Option<usize>, + + // If set, counts down with each write, and writes return an error + // when it hits 0 + pub max_writes: Option<usize>, + + // If set, attempting to write when max_writes == Some(0) will be an + // error; otherwise, it will return Ok(0). + pub error_after_max_writes: bool, +} + +impl Write for ProgrammableSink { + fn write(&mut self, data: &[u8]) -> io::Result<usize> { + if self.always_write_error { + return Err(io::Error::new(io::ErrorKind::Other, "test - always_write_error")); + } + + match self.max_writes { + Some(0) if self.error_after_max_writes => { + return Err(io::Error::new(io::ErrorKind::Other, "test - max_writes")); + } + Some(0) => return Ok(0), + Some(ref mut count) => *count -= 1, + None => {} + } + + let len = match self.accept_prefix { + None => data.len(), + Some(prefix) => data.len().min(prefix), + }; + + let data = &data[..len]; + self.buffer.extend_from_slice(data); + + Ok(len) + } + + fn flush(&mut self) -> io::Result<()> { + if self.always_flush_error { + Err(io::Error::new(io::ErrorKind::Other, "test - always_flush_error")) + } else { + self.flushed = true; + Ok(()) + } + } +} + +/// Previously the `LineWriter` could successfully write some bytes but +/// then fail to report that it has done so. Additionally, an erroneous +/// flush after a successful write was permanently ignored. +/// +/// Test that a line writer correctly reports the number of written bytes, +/// and that it attempts to flush buffered lines from previous writes +/// before processing new data +/// +/// Regression test for #37807 +#[test] +fn erroneous_flush_retried() { + let writer = ProgrammableSink { + // Only write up to 4 bytes at a time + accept_prefix: Some(4), + + // Accept the first two writes, then error the others + max_writes: Some(2), + error_after_max_writes: true, + + ..Default::default() + }; + + // This should write the first 4 bytes. The rest will be buffered, out + // to the last newline. + let mut writer = LineWriter::new(writer); + assert_eq!(writer.write(b"a\nb\nc\nd\ne").unwrap(), 8); + + // This write should attempt to flush "c\nd\n", then buffer "e". No + // errors should happen here because no further writes should be + // attempted against `writer`. + assert_eq!(writer.write(b"e").unwrap(), 1); + assert_eq!(&writer.get_ref().buffer, b"a\nb\nc\nd\n"); +} + +#[test] +fn line_vectored() { + let mut a = LineWriter::new(Vec::new()); + assert_eq!( + a.write_vectored(&[ + IoSlice::new(&[]), + IoSlice::new(b"\n"), + IoSlice::new(&[]), + IoSlice::new(b"a"), + ]) + .unwrap(), + 2, + ); + assert_eq!(a.get_ref(), b"\n"); + + assert_eq!( + a.write_vectored(&[ + IoSlice::new(&[]), + IoSlice::new(b"b"), + IoSlice::new(&[]), + IoSlice::new(b"a"), + IoSlice::new(&[]), + IoSlice::new(b"c"), + ]) + .unwrap(), + 3, + ); + assert_eq!(a.get_ref(), b"\n"); + a.flush().unwrap(); + assert_eq!(a.get_ref(), b"\nabac"); + assert_eq!(a.write_vectored(&[]).unwrap(), 0); + assert_eq!( + a.write_vectored(&[ + IoSlice::new(&[]), + IoSlice::new(&[]), + IoSlice::new(&[]), + IoSlice::new(&[]), + ]) + .unwrap(), + 0, + ); + assert_eq!(a.write_vectored(&[IoSlice::new(b"a\nb"),]).unwrap(), 3); + assert_eq!(a.get_ref(), b"\nabaca\nb"); +} + +#[test] +fn line_vectored_partial_and_errors() { + use crate::collections::VecDeque; + + enum Call { + Write { inputs: Vec<&'static [u8]>, output: io::Result<usize> }, + Flush { output: io::Result<()> }, + } + + #[derive(Default)] + struct Writer { + calls: VecDeque<Call>, + } + + impl Write for Writer { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.write_vectored(&[IoSlice::new(buf)]) + } + + fn write_vectored(&mut self, buf: &[IoSlice<'_>]) -> io::Result<usize> { + match self.calls.pop_front().expect("unexpected call to write") { + Call::Write { inputs, output } => { + assert_eq!(inputs, buf.iter().map(|b| &**b).collect::<Vec<_>>()); + output + } + Call::Flush { .. } => panic!("unexpected call to write; expected a flush"), + } + } + + fn is_write_vectored(&self) -> bool { + true + } + + fn flush(&mut self) -> io::Result<()> { + match self.calls.pop_front().expect("Unexpected call to flush") { + Call::Flush { output } => output, + Call::Write { .. } => panic!("unexpected call to flush; expected a write"), + } + } + } + + impl Drop for Writer { + fn drop(&mut self) { + if !thread::panicking() { + assert_eq!(self.calls.len(), 0); + } + } + } + + // partial writes keep going + let mut a = LineWriter::new(Writer::default()); + a.write_vectored(&[IoSlice::new(&[]), IoSlice::new(b"abc")]).unwrap(); + + a.get_mut().calls.push_back(Call::Write { inputs: vec![b"abc"], output: Ok(1) }); + a.get_mut().calls.push_back(Call::Write { inputs: vec![b"bc"], output: Ok(2) }); + a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\n"], output: Ok(2) }); + + a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\n")]).unwrap(); + + a.get_mut().calls.push_back(Call::Flush { output: Ok(()) }); + a.flush().unwrap(); + + // erroneous writes stop and don't write more + a.get_mut().calls.push_back(Call::Write { inputs: vec![b"x", b"\na"], output: Err(err()) }); + a.get_mut().calls.push_back(Call::Flush { output: Ok(()) }); + assert!(a.write_vectored(&[IoSlice::new(b"x"), IoSlice::new(b"\na")]).is_err()); + a.flush().unwrap(); + + fn err() -> io::Error { + io::Error::new(io::ErrorKind::Other, "x") + } +} + +/// Test that, in cases where vectored writing is not enabled, the +/// LineWriter uses the normal `write` call, which more-correctly handles +/// partial lines +#[test] +fn line_vectored_ignored() { + let writer = ProgrammableSink::default(); + let mut writer = LineWriter::new(writer); + + let content = [ + IoSlice::new(&[]), + IoSlice::new(b"Line 1\nLine"), + IoSlice::new(b" 2\nLine 3\nL"), + IoSlice::new(&[]), + IoSlice::new(&[]), + IoSlice::new(b"ine 4"), + IoSlice::new(b"\nLine 5\n"), + ]; + + let count = writer.write_vectored(&content).unwrap(); + assert_eq!(count, 11); + assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); + + let count = writer.write_vectored(&content[2..]).unwrap(); + assert_eq!(count, 11); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n"); + + let count = writer.write_vectored(&content[5..]).unwrap(); + assert_eq!(count, 5); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n"); + + let count = writer.write_vectored(&content[6..]).unwrap(); + assert_eq!(count, 8); + assert_eq!( + writer.get_ref().buffer.as_slice(), + b"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n".as_ref() + ); +} + +/// Test that, given this input: +/// +/// Line 1\n +/// Line 2\n +/// Line 3\n +/// Line 4 +/// +/// And given a result that only writes to midway through Line 2 +/// +/// That only up to the end of Line 3 is buffered +/// +/// This behavior is desirable because it prevents flushing partial lines +#[test] +fn partial_write_buffers_line() { + let writer = ProgrammableSink { accept_prefix: Some(13), ..Default::default() }; + let mut writer = LineWriter::new(writer); + + assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3\nLine4").unwrap(), 21); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2"); + + assert_eq!(writer.write(b"Line 4").unwrap(), 6); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\n"); +} + +/// Test that, given this input: +/// +/// Line 1\n +/// Line 2\n +/// Line 3 +/// +/// And given that the full write of lines 1 and 2 was successful +/// That data up to Line 3 is buffered +#[test] +fn partial_line_buffered_after_line_write() { + let writer = ProgrammableSink::default(); + let mut writer = LineWriter::new(writer); + + assert_eq!(writer.write(b"Line 1\nLine 2\nLine 3").unwrap(), 20); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\n"); + + assert!(writer.flush().is_ok()); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3"); +} + +/// Test that, given a partial line that exceeds the length of +/// LineBuffer's buffer (that is, without a trailing newline), that that +/// line is written to the inner writer +#[test] +fn long_line_flushed() { + let writer = ProgrammableSink::default(); + let mut writer = LineWriter::with_capacity(5, writer); + + assert_eq!(writer.write(b"0123456789").unwrap(), 10); + assert_eq!(&writer.get_ref().buffer, b"0123456789"); +} + +/// Test that, given a very long partial line *after* successfully +/// flushing a complete line, that that line is buffered unconditionally, +/// and no additional writes take place. This assures the property that +/// `write` should make at-most-one attempt to write new data. +#[test] +fn line_long_tail_not_flushed() { + let writer = ProgrammableSink::default(); + let mut writer = LineWriter::with_capacity(5, writer); + + // Assert that Line 1\n is flushed, and 01234 is buffered + assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12); + assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); + + // Because the buffer is full, this subsequent write will flush it + assert_eq!(writer.write(b"5").unwrap(), 1); + assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234"); +} + +/// Test that, if an attempt to pre-flush buffered data returns Ok(0), +/// this is propagated as an error. +#[test] +fn line_buffer_write0_error() { + let writer = ProgrammableSink { + // Accept one write, then return Ok(0) on subsequent ones + max_writes: Some(1), + + ..Default::default() + }; + let mut writer = LineWriter::new(writer); + + // This should write "Line 1\n" and buffer "Partial" + assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14); + assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); + + // This will attempt to flush "partial", which will return Ok(0), which + // needs to be an error, because we've already informed the client + // that we accepted the write. + let err = writer.write(b" Line End\n").unwrap_err(); + assert_eq!(err.kind(), ErrorKind::WriteZero); + assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); +} + +/// Test that, if a write returns Ok(0) after a successful pre-flush, this +/// is propagated as Ok(0) +#[test] +fn line_buffer_write0_normal() { + let writer = ProgrammableSink { + // Accept two writes, then return Ok(0) on subsequent ones + max_writes: Some(2), + + ..Default::default() + }; + let mut writer = LineWriter::new(writer); + + // This should write "Line 1\n" and buffer "Partial" + assert_eq!(writer.write(b"Line 1\nPartial").unwrap(), 14); + assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); + + // This will flush partial, which will succeed, but then return Ok(0) + // when flushing " Line End\n" + assert_eq!(writer.write(b" Line End\n").unwrap(), 0); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nPartial"); +} + +/// LineWriter has a custom `write_all`; make sure it works correctly +#[test] +fn line_write_all() { + let writer = ProgrammableSink { + // Only write 5 bytes at a time + accept_prefix: Some(5), + ..Default::default() + }; + let mut writer = LineWriter::new(writer); + + writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial").unwrap(); + assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3\nLine 4\n"); + writer.write_all(b" Line 5\n").unwrap(); + assert_eq!( + writer.get_ref().buffer.as_slice(), + b"Line 1\nLine 2\nLine 3\nLine 4\nPartial Line 5\n".as_ref(), + ); +} + +#[test] +fn line_write_all_error() { + let writer = ProgrammableSink { + // Only accept up to 3 writes of up to 5 bytes each + accept_prefix: Some(5), + max_writes: Some(3), + ..Default::default() + }; + + let mut writer = LineWriter::new(writer); + let res = writer.write_all(b"Line 1\nLine 2\nLine 3\nLine 4\nPartial"); + assert!(res.is_err()); + // An error from write_all leaves everything in an indeterminate state, + // so there's nothing else to test here +} + +/// Under certain circumstances, the old implementation of LineWriter +/// would try to buffer "to the last newline" but be forced to buffer +/// less than that, leading to inappropriate partial line writes. +/// Regression test for that issue. +#[test] +fn partial_multiline_buffering() { + let writer = ProgrammableSink { + // Write only up to 5 bytes at a time + accept_prefix: Some(5), + ..Default::default() + }; + + let mut writer = LineWriter::with_capacity(10, writer); + + let content = b"AAAAABBBBB\nCCCCDDDDDD\nEEE"; + + // When content is written, LineWriter will try to write blocks A, B, + // C, and D. Only block A will succeed. Under the old behavior, LineWriter + // would then try to buffer B, C and D, but because its capacity is 10, + // it will only be able to buffer B and C. We don't want to buffer + // partial lines concurrent with whole lines, so the correct behavior + // is to buffer only block B (out to the newline) + assert_eq!(writer.write(content).unwrap(), 11); + assert_eq!(writer.get_ref().buffer, *b"AAAAA"); + + writer.flush().unwrap(); + assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB\n"); +} + +/// Same as test_partial_multiline_buffering, but in the event NO full lines +/// fit in the buffer, just buffer as much as possible +#[test] +fn partial_multiline_buffering_without_full_line() { + let writer = ProgrammableSink { + // Write only up to 5 bytes at a time + accept_prefix: Some(5), + ..Default::default() + }; + + let mut writer = LineWriter::with_capacity(5, writer); + + let content = b"AAAAABBBBBBBBBB\nCCCCC\nDDDDD"; + + // When content is written, LineWriter will try to write blocks A, B, + // and C. Only block A will succeed. Under the old behavior, LineWriter + // would then try to buffer B and C, but because its capacity is 5, + // it will only be able to buffer part of B. Because it's not possible + // for it to buffer any complete lines, it should buffer as much of B as + // possible + assert_eq!(writer.write(content).unwrap(), 10); + assert_eq!(writer.get_ref().buffer, *b"AAAAA"); + + writer.flush().unwrap(); + assert_eq!(writer.get_ref().buffer, *b"AAAAABBBBB"); +} + +#[derive(Debug, Clone, PartialEq, Eq)] +enum RecordedEvent { + Write(String), + Flush, +} + +#[derive(Debug, Clone, Default)] +struct WriteRecorder { + pub events: Vec<RecordedEvent>, +} + +impl Write for WriteRecorder { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + use crate::str::from_utf8; + + self.events.push(RecordedEvent::Write(from_utf8(buf).unwrap().to_string())); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + self.events.push(RecordedEvent::Flush); + Ok(()) + } +} + +/// Test that a normal, formatted writeln only results in a single write +/// call to the underlying writer. A naive implementation of +/// LineWriter::write_all results in two writes: one of the buffered data, +/// and another of the final substring in the formatted set +#[test] +fn single_formatted_write() { + let writer = WriteRecorder::default(); + let mut writer = LineWriter::new(writer); + + // Under a naive implementation of LineWriter, this will result in two + // writes: "hello, world" and "!\n", because write() has to flush the + // buffer before attempting to write the last "!\n". write_all shouldn't + // have this limitation. + writeln!(&mut writer, "{}, {}!", "hello", "world").unwrap(); + assert_eq!(writer.get_ref().events, [RecordedEvent::Write("hello, world!\n".to_string())]); +} diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 58343f66f3f..5733735dc4a 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::io::prelude::*; use crate::cmp; @@ -447,531 +450,3 @@ impl Write for Cursor<Box<[u8]>> { Ok(()) } } - -#[cfg(test)] -mod tests { - use crate::io::prelude::*; - use crate::io::{Cursor, IoSlice, IoSliceMut, SeekFrom}; - - #[test] - fn test_vec_writer() { - let mut writer = Vec::new(); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); - assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); - assert_eq!( - writer - .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) - .unwrap(), - 3 - ); - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(writer, b); - } - - #[test] - fn test_mem_writer() { - let mut writer = Cursor::new(Vec::new()); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); - assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); - assert_eq!( - writer - .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) - .unwrap(), - 3 - ); - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(&writer.get_ref()[..], b); - } - - #[test] - fn test_mem_mut_writer() { - let mut vec = Vec::new(); - let mut writer = Cursor::new(&mut vec); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); - assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); - assert_eq!( - writer - .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) - .unwrap(), - 3 - ); - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(&writer.get_ref()[..], b); - } - - #[test] - fn test_box_slice_writer() { - let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.position(), 1); - assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); - assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); - assert_eq!(writer.position(), 8); - assert_eq!(writer.write(&[]).unwrap(), 0); - assert_eq!(writer.position(), 8); - - assert_eq!(writer.write(&[8, 9]).unwrap(), 1); - assert_eq!(writer.write(&[10]).unwrap(), 0); - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; - assert_eq!(&**writer.get_ref(), b); - } - - #[test] - fn test_box_slice_writer_vectored() { - let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1); - assert_eq!(writer.position(), 1); - assert_eq!( - writer - .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7]),]) - .unwrap(), - 7, - ); - assert_eq!(writer.position(), 8); - assert_eq!(writer.write_vectored(&[]).unwrap(), 0); - assert_eq!(writer.position(), 8); - - assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1); - assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0); - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; - assert_eq!(&**writer.get_ref(), b); - } - - #[test] - fn test_buf_writer() { - let mut buf = [0 as u8; 9]; - { - let mut writer = Cursor::new(&mut buf[..]); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.position(), 1); - assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); - assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); - assert_eq!(writer.position(), 8); - assert_eq!(writer.write(&[]).unwrap(), 0); - assert_eq!(writer.position(), 8); - - assert_eq!(writer.write(&[8, 9]).unwrap(), 1); - assert_eq!(writer.write(&[10]).unwrap(), 0); - } - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; - assert_eq!(buf, b); - } - - #[test] - fn test_buf_writer_vectored() { - let mut buf = [0 as u8; 9]; - { - let mut writer = Cursor::new(&mut buf[..]); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1); - assert_eq!(writer.position(), 1); - assert_eq!( - writer - .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7])],) - .unwrap(), - 7, - ); - assert_eq!(writer.position(), 8); - assert_eq!(writer.write_vectored(&[]).unwrap(), 0); - assert_eq!(writer.position(), 8); - - assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1); - assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0); - } - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; - assert_eq!(buf, b); - } - - #[test] - fn test_buf_writer_seek() { - let mut buf = [0 as u8; 8]; - { - let mut writer = Cursor::new(&mut buf[..]); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write(&[1]).unwrap(), 1); - assert_eq!(writer.position(), 1); - - assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2); - assert_eq!(writer.position(), 2); - assert_eq!(writer.write(&[2]).unwrap(), 1); - assert_eq!(writer.position(), 3); - - assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1); - assert_eq!(writer.position(), 1); - assert_eq!(writer.write(&[3]).unwrap(), 1); - assert_eq!(writer.position(), 2); - - assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); - assert_eq!(writer.position(), 7); - assert_eq!(writer.write(&[4]).unwrap(), 1); - assert_eq!(writer.position(), 8); - } - let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4]; - assert_eq!(buf, b); - } - - #[test] - fn test_buf_writer_error() { - let mut buf = [0 as u8; 2]; - let mut writer = Cursor::new(&mut buf[..]); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.write(&[0, 0]).unwrap(), 1); - assert_eq!(writer.write(&[0, 0]).unwrap(), 0); - } - - #[test] - fn test_mem_reader() { - let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); - let mut buf = []; - assert_eq!(reader.read(&mut buf).unwrap(), 0); - assert_eq!(reader.position(), 0); - let mut buf = [0]; - assert_eq!(reader.read(&mut buf).unwrap(), 1); - assert_eq!(reader.position(), 1); - let b: &[_] = &[0]; - assert_eq!(buf, b); - let mut buf = [0; 4]; - assert_eq!(reader.read(&mut buf).unwrap(), 4); - assert_eq!(reader.position(), 5); - let b: &[_] = &[1, 2, 3, 4]; - assert_eq!(buf, b); - assert_eq!(reader.read(&mut buf).unwrap(), 3); - let b: &[_] = &[5, 6, 7]; - assert_eq!(&buf[..3], b); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn test_mem_reader_vectored() { - let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); - let mut buf = []; - assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); - assert_eq!(reader.position(), 0); - let mut buf = [0]; - assert_eq!( - reader - .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]) - .unwrap(), - 1, - ); - assert_eq!(reader.position(), 1); - let b: &[_] = &[0]; - assert_eq!(buf, b); - let mut buf1 = [0; 4]; - let mut buf2 = [0; 4]; - assert_eq!( - reader - .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2),]) - .unwrap(), - 7, - ); - let b1: &[_] = &[1, 2, 3, 4]; - let b2: &[_] = &[5, 6, 7]; - assert_eq!(buf1, b1); - assert_eq!(&buf2[..3], b2); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn test_boxed_slice_reader() { - let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); - let mut buf = []; - assert_eq!(reader.read(&mut buf).unwrap(), 0); - assert_eq!(reader.position(), 0); - let mut buf = [0]; - assert_eq!(reader.read(&mut buf).unwrap(), 1); - assert_eq!(reader.position(), 1); - let b: &[_] = &[0]; - assert_eq!(buf, b); - let mut buf = [0; 4]; - assert_eq!(reader.read(&mut buf).unwrap(), 4); - assert_eq!(reader.position(), 5); - let b: &[_] = &[1, 2, 3, 4]; - assert_eq!(buf, b); - assert_eq!(reader.read(&mut buf).unwrap(), 3); - let b: &[_] = &[5, 6, 7]; - assert_eq!(&buf[..3], b); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn test_boxed_slice_reader_vectored() { - let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); - let mut buf = []; - assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); - assert_eq!(reader.position(), 0); - let mut buf = [0]; - assert_eq!( - reader - .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]) - .unwrap(), - 1, - ); - assert_eq!(reader.position(), 1); - let b: &[_] = &[0]; - assert_eq!(buf, b); - let mut buf1 = [0; 4]; - let mut buf2 = [0; 4]; - assert_eq!( - reader - .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) - .unwrap(), - 7, - ); - let b1: &[_] = &[1, 2, 3, 4]; - let b2: &[_] = &[5, 6, 7]; - assert_eq!(buf1, b1); - assert_eq!(&buf2[..3], b2); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn read_to_end() { - let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); - let mut v = Vec::new(); - reader.read_to_end(&mut v).unwrap(); - assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]); - } - - #[test] - fn test_slice_reader() { - let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; - let reader = &mut &in_buf[..]; - let mut buf = []; - assert_eq!(reader.read(&mut buf).unwrap(), 0); - let mut buf = [0]; - assert_eq!(reader.read(&mut buf).unwrap(), 1); - assert_eq!(reader.len(), 7); - let b: &[_] = &[0]; - assert_eq!(&buf[..], b); - let mut buf = [0; 4]; - assert_eq!(reader.read(&mut buf).unwrap(), 4); - assert_eq!(reader.len(), 3); - let b: &[_] = &[1, 2, 3, 4]; - assert_eq!(&buf[..], b); - assert_eq!(reader.read(&mut buf).unwrap(), 3); - let b: &[_] = &[5, 6, 7]; - assert_eq!(&buf[..3], b); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn test_slice_reader_vectored() { - let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; - let reader = &mut &in_buf[..]; - let mut buf = []; - assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); - let mut buf = [0]; - assert_eq!( - reader - .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]) - .unwrap(), - 1, - ); - assert_eq!(reader.len(), 7); - let b: &[_] = &[0]; - assert_eq!(buf, b); - let mut buf1 = [0; 4]; - let mut buf2 = [0; 4]; - assert_eq!( - reader - .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) - .unwrap(), - 7, - ); - let b1: &[_] = &[1, 2, 3, 4]; - let b2: &[_] = &[5, 6, 7]; - assert_eq!(buf1, b1); - assert_eq!(&buf2[..3], b2); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn test_read_exact() { - let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; - let reader = &mut &in_buf[..]; - let mut buf = []; - assert!(reader.read_exact(&mut buf).is_ok()); - let mut buf = [8]; - assert!(reader.read_exact(&mut buf).is_ok()); - assert_eq!(buf[0], 0); - assert_eq!(reader.len(), 7); - let mut buf = [0, 0, 0, 0, 0, 0, 0]; - assert!(reader.read_exact(&mut buf).is_ok()); - assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]); - assert_eq!(reader.len(), 0); - let mut buf = [0]; - assert!(reader.read_exact(&mut buf).is_err()); - } - - #[test] - fn test_buf_reader() { - let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; - let mut reader = Cursor::new(&in_buf[..]); - let mut buf = []; - assert_eq!(reader.read(&mut buf).unwrap(), 0); - assert_eq!(reader.position(), 0); - let mut buf = [0]; - assert_eq!(reader.read(&mut buf).unwrap(), 1); - assert_eq!(reader.position(), 1); - let b: &[_] = &[0]; - assert_eq!(buf, b); - let mut buf = [0; 4]; - assert_eq!(reader.read(&mut buf).unwrap(), 4); - assert_eq!(reader.position(), 5); - let b: &[_] = &[1, 2, 3, 4]; - assert_eq!(buf, b); - assert_eq!(reader.read(&mut buf).unwrap(), 3); - let b: &[_] = &[5, 6, 7]; - assert_eq!(&buf[..3], b); - assert_eq!(reader.read(&mut buf).unwrap(), 0); - } - - #[test] - fn seek_past_end() { - let buf = [0xff]; - let mut r = Cursor::new(&buf[..]); - assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); - assert_eq!(r.read(&mut [0]).unwrap(), 0); - - let mut r = Cursor::new(vec![10]); - assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); - assert_eq!(r.read(&mut [0]).unwrap(), 0); - - let mut buf = [0]; - let mut r = Cursor::new(&mut buf[..]); - assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); - assert_eq!(r.write(&[3]).unwrap(), 0); - - let mut r = Cursor::new(vec![10].into_boxed_slice()); - assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); - assert_eq!(r.write(&[3]).unwrap(), 0); - } - - #[test] - fn seek_past_i64() { - let buf = [0xff]; - let mut r = Cursor::new(&buf[..]); - assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); - assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); - assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); - assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); - assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); - assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); - - let mut r = Cursor::new(vec![10]); - assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); - assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); - assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); - assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); - assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); - assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); - - let mut buf = [0]; - let mut r = Cursor::new(&mut buf[..]); - assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); - assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); - assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); - assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); - assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); - assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); - - let mut r = Cursor::new(vec![10].into_boxed_slice()); - assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); - assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); - assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); - assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); - assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); - assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); - } - - #[test] - fn seek_before_0() { - let buf = [0xff]; - let mut r = Cursor::new(&buf[..]); - assert!(r.seek(SeekFrom::End(-2)).is_err()); - - let mut r = Cursor::new(vec![10]); - assert!(r.seek(SeekFrom::End(-2)).is_err()); - - let mut buf = [0]; - let mut r = Cursor::new(&mut buf[..]); - assert!(r.seek(SeekFrom::End(-2)).is_err()); - - let mut r = Cursor::new(vec![10].into_boxed_slice()); - assert!(r.seek(SeekFrom::End(-2)).is_err()); - } - - #[test] - fn test_seekable_mem_writer() { - let mut writer = Cursor::new(Vec::<u8>::new()); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write(&[0]).unwrap(), 1); - assert_eq!(writer.position(), 1); - assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); - assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); - assert_eq!(writer.position(), 8); - let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; - assert_eq!(&writer.get_ref()[..], b); - - assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0); - assert_eq!(writer.position(), 0); - assert_eq!(writer.write(&[3, 4]).unwrap(), 2); - let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7]; - assert_eq!(&writer.get_ref()[..], b); - - assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3); - assert_eq!(writer.write(&[0, 1]).unwrap(), 2); - let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7]; - assert_eq!(&writer.get_ref()[..], b); - - assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); - assert_eq!(writer.write(&[1, 2]).unwrap(), 2); - let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2]; - assert_eq!(&writer.get_ref()[..], b); - - assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10); - assert_eq!(writer.write(&[1]).unwrap(), 1); - let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]; - assert_eq!(&writer.get_ref()[..], b); - } - - #[test] - fn vec_seek_past_end() { - let mut r = Cursor::new(Vec::new()); - assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); - assert_eq!(r.write(&[3]).unwrap(), 1); - } - - #[test] - fn vec_seek_before_0() { - let mut r = Cursor::new(Vec::new()); - assert!(r.seek(SeekFrom::End(-2)).is_err()); - } - - #[test] - #[cfg(target_pointer_width = "32")] - fn vec_seek_and_write_past_usize_max() { - let mut c = Cursor::new(Vec::new()); - c.set_position(usize::MAX as u64 + 1); - assert!(c.write_all(&[1, 2, 3]).is_err()); - } - - #[test] - fn test_partial_eq() { - assert_eq!(Cursor::new(Vec::<u8>::new()), Cursor::new(Vec::<u8>::new())); - } - - #[test] - fn test_eq() { - struct AssertEq<T: Eq>(pub T); - - let _: AssertEq<Cursor<Vec<u8>>> = AssertEq(Cursor::new(Vec::new())); - } -} diff --git a/library/std/src/io/cursor/tests.rs b/library/std/src/io/cursor/tests.rs new file mode 100644 index 00000000000..80d88ca66f6 --- /dev/null +++ b/library/std/src/io/cursor/tests.rs @@ -0,0 +1,516 @@ +use crate::io::prelude::*; +use crate::io::{Cursor, IoSlice, IoSliceMut, SeekFrom}; + +#[test] +fn test_vec_writer() { + let mut writer = Vec::new(); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); + assert_eq!( + writer + .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) + .unwrap(), + 3 + ); + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(writer, b); +} + +#[test] +fn test_mem_writer() { + let mut writer = Cursor::new(Vec::new()); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); + assert_eq!( + writer + .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) + .unwrap(), + 3 + ); + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(&writer.get_ref()[..], b); +} + +#[test] +fn test_mem_mut_writer() { + let mut vec = Vec::new(); + let mut writer = Cursor::new(&mut vec); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); + assert_eq!( + writer + .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) + .unwrap(), + 3 + ); + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(&writer.get_ref()[..], b); +} + +#[test] +fn test_box_slice_writer() { + let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.position(), 1); + assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); + assert_eq!(writer.position(), 8); + assert_eq!(writer.write(&[]).unwrap(), 0); + assert_eq!(writer.position(), 8); + + assert_eq!(writer.write(&[8, 9]).unwrap(), 1); + assert_eq!(writer.write(&[10]).unwrap(), 0); + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; + assert_eq!(&**writer.get_ref(), b); +} + +#[test] +fn test_box_slice_writer_vectored() { + let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1); + assert_eq!(writer.position(), 1); + assert_eq!( + writer.write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7]),]).unwrap(), + 7, + ); + assert_eq!(writer.position(), 8); + assert_eq!(writer.write_vectored(&[]).unwrap(), 0); + assert_eq!(writer.position(), 8); + + assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1); + assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0); + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; + assert_eq!(&**writer.get_ref(), b); +} + +#[test] +fn test_buf_writer() { + let mut buf = [0 as u8; 9]; + { + let mut writer = Cursor::new(&mut buf[..]); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.position(), 1); + assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); + assert_eq!(writer.position(), 8); + assert_eq!(writer.write(&[]).unwrap(), 0); + assert_eq!(writer.position(), 8); + + assert_eq!(writer.write(&[8, 9]).unwrap(), 1); + assert_eq!(writer.write(&[10]).unwrap(), 0); + } + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; + assert_eq!(buf, b); +} + +#[test] +fn test_buf_writer_vectored() { + let mut buf = [0 as u8; 9]; + { + let mut writer = Cursor::new(&mut buf[..]); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1); + assert_eq!(writer.position(), 1); + assert_eq!( + writer + .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7])],) + .unwrap(), + 7, + ); + assert_eq!(writer.position(), 8); + assert_eq!(writer.write_vectored(&[]).unwrap(), 0); + assert_eq!(writer.position(), 8); + + assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1); + assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0); + } + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; + assert_eq!(buf, b); +} + +#[test] +fn test_buf_writer_seek() { + let mut buf = [0 as u8; 8]; + { + let mut writer = Cursor::new(&mut buf[..]); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write(&[1]).unwrap(), 1); + assert_eq!(writer.position(), 1); + + assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2); + assert_eq!(writer.position(), 2); + assert_eq!(writer.write(&[2]).unwrap(), 1); + assert_eq!(writer.position(), 3); + + assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1); + assert_eq!(writer.position(), 1); + assert_eq!(writer.write(&[3]).unwrap(), 1); + assert_eq!(writer.position(), 2); + + assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); + assert_eq!(writer.position(), 7); + assert_eq!(writer.write(&[4]).unwrap(), 1); + assert_eq!(writer.position(), 8); + } + let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4]; + assert_eq!(buf, b); +} + +#[test] +fn test_buf_writer_error() { + let mut buf = [0 as u8; 2]; + let mut writer = Cursor::new(&mut buf[..]); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.write(&[0, 0]).unwrap(), 1); + assert_eq!(writer.write(&[0, 0]).unwrap(), 0); +} + +#[test] +fn test_mem_reader() { + let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); + let mut buf = []; + assert_eq!(reader.read(&mut buf).unwrap(), 0); + assert_eq!(reader.position(), 0); + let mut buf = [0]; + assert_eq!(reader.read(&mut buf).unwrap(), 1); + assert_eq!(reader.position(), 1); + let b: &[_] = &[0]; + assert_eq!(buf, b); + let mut buf = [0; 4]; + assert_eq!(reader.read(&mut buf).unwrap(), 4); + assert_eq!(reader.position(), 5); + let b: &[_] = &[1, 2, 3, 4]; + assert_eq!(buf, b); + assert_eq!(reader.read(&mut buf).unwrap(), 3); + let b: &[_] = &[5, 6, 7]; + assert_eq!(&buf[..3], b); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn test_mem_reader_vectored() { + let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); + let mut buf = []; + assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); + assert_eq!(reader.position(), 0); + let mut buf = [0]; + assert_eq!( + reader.read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]).unwrap(), + 1, + ); + assert_eq!(reader.position(), 1); + let b: &[_] = &[0]; + assert_eq!(buf, b); + let mut buf1 = [0; 4]; + let mut buf2 = [0; 4]; + assert_eq!( + reader + .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2),]) + .unwrap(), + 7, + ); + let b1: &[_] = &[1, 2, 3, 4]; + let b2: &[_] = &[5, 6, 7]; + assert_eq!(buf1, b1); + assert_eq!(&buf2[..3], b2); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn test_boxed_slice_reader() { + let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); + let mut buf = []; + assert_eq!(reader.read(&mut buf).unwrap(), 0); + assert_eq!(reader.position(), 0); + let mut buf = [0]; + assert_eq!(reader.read(&mut buf).unwrap(), 1); + assert_eq!(reader.position(), 1); + let b: &[_] = &[0]; + assert_eq!(buf, b); + let mut buf = [0; 4]; + assert_eq!(reader.read(&mut buf).unwrap(), 4); + assert_eq!(reader.position(), 5); + let b: &[_] = &[1, 2, 3, 4]; + assert_eq!(buf, b); + assert_eq!(reader.read(&mut buf).unwrap(), 3); + let b: &[_] = &[5, 6, 7]; + assert_eq!(&buf[..3], b); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn test_boxed_slice_reader_vectored() { + let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); + let mut buf = []; + assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); + assert_eq!(reader.position(), 0); + let mut buf = [0]; + assert_eq!( + reader.read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]).unwrap(), + 1, + ); + assert_eq!(reader.position(), 1); + let b: &[_] = &[0]; + assert_eq!(buf, b); + let mut buf1 = [0; 4]; + let mut buf2 = [0; 4]; + assert_eq!( + reader + .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) + .unwrap(), + 7, + ); + let b1: &[_] = &[1, 2, 3, 4]; + let b2: &[_] = &[5, 6, 7]; + assert_eq!(buf1, b1); + assert_eq!(&buf2[..3], b2); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn read_to_end() { + let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); + let mut v = Vec::new(); + reader.read_to_end(&mut v).unwrap(); + assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]); +} + +#[test] +fn test_slice_reader() { + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; + let reader = &mut &in_buf[..]; + let mut buf = []; + assert_eq!(reader.read(&mut buf).unwrap(), 0); + let mut buf = [0]; + assert_eq!(reader.read(&mut buf).unwrap(), 1); + assert_eq!(reader.len(), 7); + let b: &[_] = &[0]; + assert_eq!(&buf[..], b); + let mut buf = [0; 4]; + assert_eq!(reader.read(&mut buf).unwrap(), 4); + assert_eq!(reader.len(), 3); + let b: &[_] = &[1, 2, 3, 4]; + assert_eq!(&buf[..], b); + assert_eq!(reader.read(&mut buf).unwrap(), 3); + let b: &[_] = &[5, 6, 7]; + assert_eq!(&buf[..3], b); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn test_slice_reader_vectored() { + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; + let reader = &mut &in_buf[..]; + let mut buf = []; + assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); + let mut buf = [0]; + assert_eq!( + reader.read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]).unwrap(), + 1, + ); + assert_eq!(reader.len(), 7); + let b: &[_] = &[0]; + assert_eq!(buf, b); + let mut buf1 = [0; 4]; + let mut buf2 = [0; 4]; + assert_eq!( + reader + .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) + .unwrap(), + 7, + ); + let b1: &[_] = &[1, 2, 3, 4]; + let b2: &[_] = &[5, 6, 7]; + assert_eq!(buf1, b1); + assert_eq!(&buf2[..3], b2); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn test_read_exact() { + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; + let reader = &mut &in_buf[..]; + let mut buf = []; + assert!(reader.read_exact(&mut buf).is_ok()); + let mut buf = [8]; + assert!(reader.read_exact(&mut buf).is_ok()); + assert_eq!(buf[0], 0); + assert_eq!(reader.len(), 7); + let mut buf = [0, 0, 0, 0, 0, 0, 0]; + assert!(reader.read_exact(&mut buf).is_ok()); + assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]); + assert_eq!(reader.len(), 0); + let mut buf = [0]; + assert!(reader.read_exact(&mut buf).is_err()); +} + +#[test] +fn test_buf_reader() { + let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; + let mut reader = Cursor::new(&in_buf[..]); + let mut buf = []; + assert_eq!(reader.read(&mut buf).unwrap(), 0); + assert_eq!(reader.position(), 0); + let mut buf = [0]; + assert_eq!(reader.read(&mut buf).unwrap(), 1); + assert_eq!(reader.position(), 1); + let b: &[_] = &[0]; + assert_eq!(buf, b); + let mut buf = [0; 4]; + assert_eq!(reader.read(&mut buf).unwrap(), 4); + assert_eq!(reader.position(), 5); + let b: &[_] = &[1, 2, 3, 4]; + assert_eq!(buf, b); + assert_eq!(reader.read(&mut buf).unwrap(), 3); + let b: &[_] = &[5, 6, 7]; + assert_eq!(&buf[..3], b); + assert_eq!(reader.read(&mut buf).unwrap(), 0); +} + +#[test] +fn seek_past_end() { + let buf = [0xff]; + let mut r = Cursor::new(&buf[..]); + assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); + assert_eq!(r.read(&mut [0]).unwrap(), 0); + + let mut r = Cursor::new(vec![10]); + assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); + assert_eq!(r.read(&mut [0]).unwrap(), 0); + + let mut buf = [0]; + let mut r = Cursor::new(&mut buf[..]); + assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); + assert_eq!(r.write(&[3]).unwrap(), 0); + + let mut r = Cursor::new(vec![10].into_boxed_slice()); + assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); + assert_eq!(r.write(&[3]).unwrap(), 0); +} + +#[test] +fn seek_past_i64() { + let buf = [0xff]; + let mut r = Cursor::new(&buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut buf = [0]; + let mut r = Cursor::new(&mut buf[..]); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); + + let mut r = Cursor::new(vec![10].into_boxed_slice()); + assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); + assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); + assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); + assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); + assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); + assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); +} + +#[test] +fn seek_before_0() { + let buf = [0xff]; + let mut r = Cursor::new(&buf[..]); + assert!(r.seek(SeekFrom::End(-2)).is_err()); + + let mut r = Cursor::new(vec![10]); + assert!(r.seek(SeekFrom::End(-2)).is_err()); + + let mut buf = [0]; + let mut r = Cursor::new(&mut buf[..]); + assert!(r.seek(SeekFrom::End(-2)).is_err()); + + let mut r = Cursor::new(vec![10].into_boxed_slice()); + assert!(r.seek(SeekFrom::End(-2)).is_err()); +} + +#[test] +fn test_seekable_mem_writer() { + let mut writer = Cursor::new(Vec::<u8>::new()); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write(&[0]).unwrap(), 1); + assert_eq!(writer.position(), 1); + assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); + assert_eq!(writer.position(), 8); + let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; + assert_eq!(&writer.get_ref()[..], b); + + assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0); + assert_eq!(writer.position(), 0); + assert_eq!(writer.write(&[3, 4]).unwrap(), 2); + let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7]; + assert_eq!(&writer.get_ref()[..], b); + + assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3); + assert_eq!(writer.write(&[0, 1]).unwrap(), 2); + let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7]; + assert_eq!(&writer.get_ref()[..], b); + + assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); + assert_eq!(writer.write(&[1, 2]).unwrap(), 2); + let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2]; + assert_eq!(&writer.get_ref()[..], b); + + assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10); + assert_eq!(writer.write(&[1]).unwrap(), 1); + let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]; + assert_eq!(&writer.get_ref()[..], b); +} + +#[test] +fn vec_seek_past_end() { + let mut r = Cursor::new(Vec::new()); + assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); + assert_eq!(r.write(&[3]).unwrap(), 1); +} + +#[test] +fn vec_seek_before_0() { + let mut r = Cursor::new(Vec::new()); + assert!(r.seek(SeekFrom::End(-2)).is_err()); +} + +#[test] +#[cfg(target_pointer_width = "32")] +fn vec_seek_and_write_past_usize_max() { + let mut c = Cursor::new(Vec::new()); + c.set_position(usize::MAX as u64 + 1); + assert!(c.write_all(&[1, 2, 3]).is_err()); +} + +#[test] +fn test_partial_eq() { + assert_eq!(Cursor::new(Vec::<u8>::new()), Cursor::new(Vec::<u8>::new())); +} + +#[test] +fn test_eq() { + struct AssertEq<T: Eq>(pub T); + + let _: AssertEq<Cursor<Vec<u8>>> = AssertEq(Cursor::new(Vec::new())); +} diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index e6eda2caf75..ba0f0a0cd71 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::convert::From; use crate::error; use crate::fmt; @@ -574,60 +577,3 @@ fn _assert_error_is_sync_send() { fn _is_sync_send<T: Sync + Send>() {} _is_sync_send::<Error>(); } - -#[cfg(test)] -mod test { - use super::{Custom, Error, ErrorKind, Repr}; - use crate::error; - use crate::fmt; - use crate::sys::decode_error_kind; - use crate::sys::os::error_string; - - #[test] - fn test_debug_error() { - let code = 6; - let msg = error_string(code); - let kind = decode_error_kind(code); - let err = Error { - repr: Repr::Custom(box Custom { - kind: ErrorKind::InvalidInput, - error: box Error { repr: super::Repr::Os(code) }, - }), - }; - let expected = format!( - "Custom {{ \ - kind: InvalidInput, \ - error: Os {{ \ - code: {:?}, \ - kind: {:?}, \ - message: {:?} \ - }} \ - }}", - code, kind, msg - ); - assert_eq!(format!("{:?}", err), expected); - } - - #[test] - fn test_downcasting() { - #[derive(Debug)] - struct TestError; - - impl fmt::Display for TestError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("asdf") - } - } - - impl error::Error for TestError {} - - // we have to call all of these UFCS style right now since method - // resolution won't implicitly drop the Send+Sync bounds - let mut err = Error::new(ErrorKind::Other, TestError); - assert!(err.get_ref().unwrap().is::<TestError>()); - assert_eq!("asdf", err.get_ref().unwrap().to_string()); - assert!(err.get_mut().unwrap().is::<TestError>()); - let extracted = err.into_inner().unwrap(); - extracted.downcast::<TestError>().unwrap(); - } -} diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs new file mode 100644 index 00000000000..0cce9368c80 --- /dev/null +++ b/library/std/src/io/error/tests.rs @@ -0,0 +1,53 @@ +use super::{Custom, Error, ErrorKind, Repr}; +use crate::error; +use crate::fmt; +use crate::sys::decode_error_kind; +use crate::sys::os::error_string; + +#[test] +fn test_debug_error() { + let code = 6; + let msg = error_string(code); + let kind = decode_error_kind(code); + let err = Error { + repr: Repr::Custom(box Custom { + kind: ErrorKind::InvalidInput, + error: box Error { repr: super::Repr::Os(code) }, + }), + }; + let expected = format!( + "Custom {{ \ + kind: InvalidInput, \ + error: Os {{ \ + code: {:?}, \ + kind: {:?}, \ + message: {:?} \ + }} \ + }}", + code, kind, msg + ); + assert_eq!(format!("{:?}", err), expected); +} + +#[test] +fn test_downcasting() { + #[derive(Debug)] + struct TestError; + + impl fmt::Display for TestError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("asdf") + } + } + + impl error::Error for TestError {} + + // we have to call all of these UFCS style right now since method + // resolution won't implicitly drop the Send+Sync bounds + let mut err = Error::new(ErrorKind::Other, TestError); + assert!(err.get_ref().unwrap().is::<TestError>()); + assert_eq!("asdf", err.get_ref().unwrap().to_string()); + assert!(err.get_mut().unwrap().is::<TestError>()); + let extracted = err.into_inner().unwrap(); + extracted.downcast::<TestError>().unwrap(); +} diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index 01dff0b3eb3..e09e7ba978e 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::cmp; use crate::fmt; use crate::io::{ @@ -397,64 +400,3 @@ impl Write for Vec<u8> { Ok(()) } } - -#[cfg(test)] -mod tests { - use crate::io::prelude::*; - - #[bench] - fn bench_read_slice(b: &mut test::Bencher) { - let buf = [5; 1024]; - let mut dst = [0; 128]; - - b.iter(|| { - let mut rd = &buf[..]; - for _ in 0..8 { - let _ = rd.read(&mut dst); - test::black_box(&dst); - } - }) - } - - #[bench] - fn bench_write_slice(b: &mut test::Bencher) { - let mut buf = [0; 1024]; - let src = [5; 128]; - - b.iter(|| { - let mut wr = &mut buf[..]; - for _ in 0..8 { - let _ = wr.write_all(&src); - test::black_box(&wr); - } - }) - } - - #[bench] - fn bench_read_vec(b: &mut test::Bencher) { - let buf = vec![5; 1024]; - let mut dst = [0; 128]; - - b.iter(|| { - let mut rd = &buf[..]; - for _ in 0..8 { - let _ = rd.read(&mut dst); - test::black_box(&dst); - } - }) - } - - #[bench] - fn bench_write_vec(b: &mut test::Bencher) { - let mut buf = Vec::with_capacity(1024); - let src = [5; 128]; - - b.iter(|| { - let mut wr = &mut buf[..]; - for _ in 0..8 { - let _ = wr.write_all(&src); - test::black_box(&wr); - } - }) - } -} diff --git a/library/std/src/io/impls/tests.rs b/library/std/src/io/impls/tests.rs new file mode 100644 index 00000000000..d1cd84a67ad --- /dev/null +++ b/library/std/src/io/impls/tests.rs @@ -0,0 +1,57 @@ +use crate::io::prelude::*; + +#[bench] +fn bench_read_slice(b: &mut test::Bencher) { + let buf = [5; 1024]; + let mut dst = [0; 128]; + + b.iter(|| { + let mut rd = &buf[..]; + for _ in 0..8 { + let _ = rd.read(&mut dst); + test::black_box(&dst); + } + }) +} + +#[bench] +fn bench_write_slice(b: &mut test::Bencher) { + let mut buf = [0; 1024]; + let src = [5; 128]; + + b.iter(|| { + let mut wr = &mut buf[..]; + for _ in 0..8 { + let _ = wr.write_all(&src); + test::black_box(&wr); + } + }) +} + +#[bench] +fn bench_read_vec(b: &mut test::Bencher) { + let buf = vec![5; 1024]; + let mut dst = [0; 128]; + + b.iter(|| { + let mut rd = &buf[..]; + for _ in 0..8 { + let _ = rd.read(&mut dst); + test::black_box(&dst); + } + }) +} + +#[bench] +fn bench_write_vec(b: &mut test::Bencher) { + let mut buf = Vec::with_capacity(1024); + let src = [5; 128]; + + b.iter(|| { + let mut wr = &mut buf[..]; + for _ in 0..8 { + let _ = wr.write_all(&src); + test::black_box(&wr); + } + }) +} diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 462b696db40..adea8a804e3 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -249,6 +249,9 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(test)] +mod tests; + use crate::cmp; use crate::fmt; use crate::memchr; @@ -2481,501 +2484,3 @@ impl<B: BufRead> Iterator for Lines<B> { } } } - -#[cfg(test)] -mod tests { - use super::{repeat, Cursor, SeekFrom}; - use crate::cmp::{self, min}; - use crate::io::prelude::*; - use crate::io::{self, IoSlice, IoSliceMut}; - use crate::ops::Deref; - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn read_until() { - let mut buf = Cursor::new(&b"12"[..]); - let mut v = Vec::new(); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2); - assert_eq!(v, b"12"); - - let mut buf = Cursor::new(&b"1233"[..]); - let mut v = Vec::new(); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3); - assert_eq!(v, b"123"); - v.truncate(0); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1); - assert_eq!(v, b"3"); - v.truncate(0); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0); - assert_eq!(v, []); - } - - #[test] - fn split() { - let buf = Cursor::new(&b"12"[..]); - let mut s = buf.split(b'3'); - assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); - assert!(s.next().is_none()); - - let buf = Cursor::new(&b"1233"[..]); - let mut s = buf.split(b'3'); - assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); - assert_eq!(s.next().unwrap().unwrap(), vec![]); - assert!(s.next().is_none()); - } - - #[test] - fn read_line() { - let mut buf = Cursor::new(&b"12"[..]); - let mut v = String::new(); - assert_eq!(buf.read_line(&mut v).unwrap(), 2); - assert_eq!(v, "12"); - - let mut buf = Cursor::new(&b"12\n\n"[..]); - let mut v = String::new(); - assert_eq!(buf.read_line(&mut v).unwrap(), 3); - assert_eq!(v, "12\n"); - v.truncate(0); - assert_eq!(buf.read_line(&mut v).unwrap(), 1); - assert_eq!(v, "\n"); - v.truncate(0); - assert_eq!(buf.read_line(&mut v).unwrap(), 0); - assert_eq!(v, ""); - } - - #[test] - fn lines() { - let buf = Cursor::new(&b"12\r"[..]); - let mut s = buf.lines(); - assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string()); - assert!(s.next().is_none()); - - let buf = Cursor::new(&b"12\r\n\n"[..]); - let mut s = buf.lines(); - assert_eq!(s.next().unwrap().unwrap(), "12".to_string()); - assert_eq!(s.next().unwrap().unwrap(), "".to_string()); - assert!(s.next().is_none()); - } - - #[test] - fn read_to_end() { - let mut c = Cursor::new(&b""[..]); - let mut v = Vec::new(); - assert_eq!(c.read_to_end(&mut v).unwrap(), 0); - assert_eq!(v, []); - - let mut c = Cursor::new(&b"1"[..]); - let mut v = Vec::new(); - assert_eq!(c.read_to_end(&mut v).unwrap(), 1); - assert_eq!(v, b"1"); - - let cap = 1024 * 1024; - let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>(); - let mut v = Vec::new(); - let (a, b) = data.split_at(data.len() / 2); - assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len()); - assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len()); - assert_eq!(v, data); - } - - #[test] - fn read_to_string() { - let mut c = Cursor::new(&b""[..]); - let mut v = String::new(); - assert_eq!(c.read_to_string(&mut v).unwrap(), 0); - assert_eq!(v, ""); - - let mut c = Cursor::new(&b"1"[..]); - let mut v = String::new(); - assert_eq!(c.read_to_string(&mut v).unwrap(), 1); - assert_eq!(v, "1"); - - let mut c = Cursor::new(&b"\xff"[..]); - let mut v = String::new(); - assert!(c.read_to_string(&mut v).is_err()); - } - - #[test] - fn read_exact() { - let mut buf = [0; 4]; - - let mut c = Cursor::new(&b""[..]); - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - - let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..])); - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"1234"); - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"5678"); - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - } - - #[test] - fn read_exact_slice() { - let mut buf = [0; 4]; - - let mut c = &b""[..]; - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - - let mut c = &b"123"[..]; - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - // make sure the optimized (early returning) method is being used - assert_eq!(&buf, &[0; 4]); - - let mut c = &b"1234"[..]; - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"1234"); - - let mut c = &b"56789"[..]; - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"5678"); - assert_eq!(c, b"9"); - } - - #[test] - fn take_eof() { - struct R; - - impl Read for R { - fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { - Err(io::Error::new(io::ErrorKind::Other, "")) - } - } - impl BufRead for R { - fn fill_buf(&mut self) -> io::Result<&[u8]> { - Err(io::Error::new(io::ErrorKind::Other, "")) - } - fn consume(&mut self, _amt: usize) {} - } - - let mut buf = [0; 1]; - assert_eq!(0, R.take(0).read(&mut buf).unwrap()); - assert_eq!(b"", R.take(0).fill_buf().unwrap()); - } - - fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) { - let mut cat = Vec::new(); - loop { - let consume = { - let buf1 = br1.fill_buf().unwrap(); - let buf2 = br2.fill_buf().unwrap(); - let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() }; - assert_eq!(buf1[..minlen], buf2[..minlen]); - cat.extend_from_slice(&buf1[..minlen]); - minlen - }; - if consume == 0 { - break; - } - br1.consume(consume); - br2.consume(consume); - } - assert_eq!(br1.fill_buf().unwrap().len(), 0); - assert_eq!(br2.fill_buf().unwrap().len(), 0); - assert_eq!(&cat[..], &exp[..]) - } - - #[test] - fn chain_bufread() { - let testdata = b"ABCDEFGHIJKL"; - let chain1 = - (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]); - let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]); - cmp_bufread(chain1, chain2, &testdata[..]); - } - - #[test] - fn chain_zero_length_read_is_not_eof() { - let a = b"A"; - let b = b"B"; - let mut s = String::new(); - let mut chain = (&a[..]).chain(&b[..]); - chain.read(&mut []).unwrap(); - chain.read_to_string(&mut s).unwrap(); - assert_eq!("AB", s); - } - - #[bench] - #[cfg_attr(target_os = "emscripten", ignore)] - fn bench_read_to_end(b: &mut test::Bencher) { - b.iter(|| { - let mut lr = repeat(1).take(10000000); - let mut vec = Vec::with_capacity(1024); - super::read_to_end(&mut lr, &mut vec) - }); - } - - #[test] - fn seek_len() -> io::Result<()> { - let mut c = Cursor::new(vec![0; 15]); - assert_eq!(c.stream_len()?, 15); - - c.seek(SeekFrom::End(0))?; - let old_pos = c.stream_position()?; - assert_eq!(c.stream_len()?, 15); - assert_eq!(c.stream_position()?, old_pos); - - c.seek(SeekFrom::Start(7))?; - c.seek(SeekFrom::Current(2))?; - let old_pos = c.stream_position()?; - assert_eq!(c.stream_len()?, 15); - assert_eq!(c.stream_position()?, old_pos); - - Ok(()) - } - - #[test] - fn seek_position() -> io::Result<()> { - // All `asserts` are duplicated here to make sure the method does not - // change anything about the seek state. - let mut c = Cursor::new(vec![0; 15]); - assert_eq!(c.stream_position()?, 0); - assert_eq!(c.stream_position()?, 0); - - c.seek(SeekFrom::End(0))?; - assert_eq!(c.stream_position()?, 15); - assert_eq!(c.stream_position()?, 15); - - c.seek(SeekFrom::Start(7))?; - c.seek(SeekFrom::Current(2))?; - assert_eq!(c.stream_position()?, 9); - assert_eq!(c.stream_position()?, 9); - - c.seek(SeekFrom::End(-3))?; - c.seek(SeekFrom::Current(1))?; - c.seek(SeekFrom::Current(-5))?; - assert_eq!(c.stream_position()?, 8); - assert_eq!(c.stream_position()?, 8); - - Ok(()) - } - - // A simple example reader which uses the default implementation of - // read_to_end. - struct ExampleSliceReader<'a> { - slice: &'a [u8], - } - - impl<'a> Read for ExampleSliceReader<'a> { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - let len = cmp::min(self.slice.len(), buf.len()); - buf[..len].copy_from_slice(&self.slice[..len]); - self.slice = &self.slice[len..]; - Ok(len) - } - } - - #[test] - fn test_read_to_end_capacity() -> io::Result<()> { - let input = &b"foo"[..]; - - // read_to_end() generally needs to over-allocate, both for efficiency - // and so that it can distinguish EOF. Assert that this is the case - // with this simple ExampleSliceReader struct, which uses the default - // implementation of read_to_end. Even though vec1 is allocated with - // exactly enough capacity for the read, read_to_end will allocate more - // space here. - let mut vec1 = Vec::with_capacity(input.len()); - ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?; - assert_eq!(vec1.len(), input.len()); - assert!(vec1.capacity() > input.len(), "allocated more"); - - // However, std::io::Take includes an implementation of read_to_end - // that will not allocate when the limit has already been reached. In - // this case, vec2 never grows. - let mut vec2 = Vec::with_capacity(input.len()); - ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?; - assert_eq!(vec2.len(), input.len()); - assert_eq!(vec2.capacity(), input.len(), "did not allocate more"); - - Ok(()) - } - - #[test] - fn io_slice_mut_advance() { - let mut buf1 = [1; 8]; - let mut buf2 = [2; 16]; - let mut buf3 = [3; 8]; - let mut bufs = &mut [ - IoSliceMut::new(&mut buf1), - IoSliceMut::new(&mut buf2), - IoSliceMut::new(&mut buf3), - ][..]; - - // Only in a single buffer.. - bufs = IoSliceMut::advance(bufs, 1); - assert_eq!(bufs[0].deref(), [1; 7].as_ref()); - assert_eq!(bufs[1].deref(), [2; 16].as_ref()); - assert_eq!(bufs[2].deref(), [3; 8].as_ref()); - - // Removing a buffer, leaving others as is. - bufs = IoSliceMut::advance(bufs, 7); - assert_eq!(bufs[0].deref(), [2; 16].as_ref()); - assert_eq!(bufs[1].deref(), [3; 8].as_ref()); - - // Removing a buffer and removing from the next buffer. - bufs = IoSliceMut::advance(bufs, 18); - assert_eq!(bufs[0].deref(), [3; 6].as_ref()); - } - - #[test] - fn io_slice_mut_advance_empty_slice() { - let empty_bufs = &mut [][..]; - // Shouldn't panic. - IoSliceMut::advance(empty_bufs, 1); - } - - #[test] - fn io_slice_mut_advance_beyond_total_length() { - let mut buf1 = [1; 8]; - let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; - - // Going beyond the total length should be ok. - bufs = IoSliceMut::advance(bufs, 9); - assert!(bufs.is_empty()); - } - - #[test] - fn io_slice_advance() { - let buf1 = [1; 8]; - let buf2 = [2; 16]; - let buf3 = [3; 8]; - let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; - - // Only in a single buffer.. - bufs = IoSlice::advance(bufs, 1); - assert_eq!(bufs[0].deref(), [1; 7].as_ref()); - assert_eq!(bufs[1].deref(), [2; 16].as_ref()); - assert_eq!(bufs[2].deref(), [3; 8].as_ref()); - - // Removing a buffer, leaving others as is. - bufs = IoSlice::advance(bufs, 7); - assert_eq!(bufs[0].deref(), [2; 16].as_ref()); - assert_eq!(bufs[1].deref(), [3; 8].as_ref()); - - // Removing a buffer and removing from the next buffer. - bufs = IoSlice::advance(bufs, 18); - assert_eq!(bufs[0].deref(), [3; 6].as_ref()); - } - - #[test] - fn io_slice_advance_empty_slice() { - let empty_bufs = &mut [][..]; - // Shouldn't panic. - IoSlice::advance(empty_bufs, 1); - } - - #[test] - fn io_slice_advance_beyond_total_length() { - let buf1 = [1; 8]; - let mut bufs = &mut [IoSlice::new(&buf1)][..]; - - // Going beyond the total length should be ok. - bufs = IoSlice::advance(bufs, 9); - assert!(bufs.is_empty()); - } - - /// Create a new writer that reads from at most `n_bufs` and reads - /// `per_call` bytes (in total) per call to write. - fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter { - TestWriter { n_bufs, per_call, written: Vec::new() } - } - - struct TestWriter { - n_bufs: usize, - per_call: usize, - written: Vec<u8>, - } - - impl Write for TestWriter { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.write_vectored(&[IoSlice::new(buf)]) - } - - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let mut left = self.per_call; - let mut written = 0; - for buf in bufs.iter().take(self.n_bufs) { - let n = min(left, buf.len()); - self.written.extend_from_slice(&buf[0..n]); - left -= n; - written += n; - } - Ok(written) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } - } - - #[test] - fn test_writer_read_from_one_buf() { - let mut writer = test_writer(1, 2); - - assert_eq!(writer.write(&[]).unwrap(), 0); - assert_eq!(writer.write_vectored(&[]).unwrap(), 0); - - // Read at most 2 bytes. - assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2); - let bufs = &[IoSlice::new(&[2, 2, 2])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 2); - - // Only read from first buf. - let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 1); - - assert_eq!(writer.written, &[1, 1, 2, 2, 3]); - } - - #[test] - fn test_writer_read_from_multiple_bufs() { - let mut writer = test_writer(3, 3); - - // Read at most 3 bytes from two buffers. - let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 3); - - // Read at most 3 bytes from three buffers. - let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 3); - - assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]); - } - - #[test] - fn test_write_all_vectored() { - #[rustfmt::skip] // Becomes unreadable otherwise. - let tests: Vec<(_, &'static [u8])> = vec![ - (vec![], &[]), - (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), - (vec![IoSlice::new(&[1])], &[1]), - (vec![IoSlice::new(&[1, 2])], &[1, 2]), - (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), - (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), - (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]), - (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), - ]; - - let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]; - - for (n_bufs, per_call) in writer_configs.iter().copied() { - for (mut input, wanted) in tests.clone().into_iter() { - let mut writer = test_writer(n_bufs, per_call); - assert!(writer.write_all_vectored(&mut *input).is_ok()); - assert_eq!(&*writer.written, &*wanted); - } - } - } -} diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 3943c66aad5..9974b65f1e1 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -1,5 +1,8 @@ #![cfg_attr(test, allow(unused))] +#[cfg(test)] +mod tests; + use crate::io::prelude::*; use crate::cell::RefCell; @@ -920,54 +923,3 @@ pub fn _eprint(args: fmt::Arguments<'_>) { #[cfg(test)] pub use realstd::io::{_eprint, _print}; - -#[cfg(test)] -mod tests { - use super::*; - use crate::panic::{RefUnwindSafe, UnwindSafe}; - use crate::thread; - - #[test] - fn stdout_unwind_safe() { - assert_unwind_safe::<Stdout>(); - } - #[test] - fn stdoutlock_unwind_safe() { - assert_unwind_safe::<StdoutLock<'_>>(); - assert_unwind_safe::<StdoutLock<'static>>(); - } - #[test] - fn stderr_unwind_safe() { - assert_unwind_safe::<Stderr>(); - } - #[test] - fn stderrlock_unwind_safe() { - assert_unwind_safe::<StderrLock<'_>>(); - assert_unwind_safe::<StderrLock<'static>>(); - } - - fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {} - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn panic_doesnt_poison() { - thread::spawn(|| { - let _a = stdin(); - let _a = _a.lock(); - let _a = stdout(); - let _a = _a.lock(); - let _a = stderr(); - let _a = _a.lock(); - panic!(); - }) - .join() - .unwrap_err(); - - let _a = stdin(); - let _a = _a.lock(); - let _a = stdout(); - let _a = _a.lock(); - let _a = stderr(); - let _a = _a.lock(); - } -} diff --git a/library/std/src/io/stdio/tests.rs b/library/std/src/io/stdio/tests.rs new file mode 100644 index 00000000000..04af500268f --- /dev/null +++ b/library/std/src/io/stdio/tests.rs @@ -0,0 +1,47 @@ +use super::*; +use crate::panic::{RefUnwindSafe, UnwindSafe}; +use crate::thread; + +#[test] +fn stdout_unwind_safe() { + assert_unwind_safe::<Stdout>(); +} +#[test] +fn stdoutlock_unwind_safe() { + assert_unwind_safe::<StdoutLock<'_>>(); + assert_unwind_safe::<StdoutLock<'static>>(); +} +#[test] +fn stderr_unwind_safe() { + assert_unwind_safe::<Stderr>(); +} +#[test] +fn stderrlock_unwind_safe() { + assert_unwind_safe::<StderrLock<'_>>(); + assert_unwind_safe::<StderrLock<'static>>(); +} + +fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn panic_doesnt_poison() { + thread::spawn(|| { + let _a = stdin(); + let _a = _a.lock(); + let _a = stdout(); + let _a = _a.lock(); + let _a = stderr(); + let _a = _a.lock(); + panic!(); + }) + .join() + .unwrap_err(); + + let _a = stdin(); + let _a = _a.lock(); + let _a = stdout(); + let _a = _a.lock(); + let _a = stderr(); + let _a = _a.lock(); +} diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs new file mode 100644 index 00000000000..913b28538b7 --- /dev/null +++ b/library/std/src/io/tests.rs @@ -0,0 +1,494 @@ +use super::{repeat, Cursor, SeekFrom}; +use crate::cmp::{self, min}; +use crate::io::prelude::*; +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::ops::Deref; + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn read_until() { + let mut buf = Cursor::new(&b"12"[..]); + let mut v = Vec::new(); + assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2); + assert_eq!(v, b"12"); + + let mut buf = Cursor::new(&b"1233"[..]); + let mut v = Vec::new(); + assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3); + assert_eq!(v, b"123"); + v.truncate(0); + assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1); + assert_eq!(v, b"3"); + v.truncate(0); + assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0); + assert_eq!(v, []); +} + +#[test] +fn split() { + let buf = Cursor::new(&b"12"[..]); + let mut s = buf.split(b'3'); + assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); + assert!(s.next().is_none()); + + let buf = Cursor::new(&b"1233"[..]); + let mut s = buf.split(b'3'); + assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); + assert_eq!(s.next().unwrap().unwrap(), vec![]); + assert!(s.next().is_none()); +} + +#[test] +fn read_line() { + let mut buf = Cursor::new(&b"12"[..]); + let mut v = String::new(); + assert_eq!(buf.read_line(&mut v).unwrap(), 2); + assert_eq!(v, "12"); + + let mut buf = Cursor::new(&b"12\n\n"[..]); + let mut v = String::new(); + assert_eq!(buf.read_line(&mut v).unwrap(), 3); + assert_eq!(v, "12\n"); + v.truncate(0); + assert_eq!(buf.read_line(&mut v).unwrap(), 1); + assert_eq!(v, "\n"); + v.truncate(0); + assert_eq!(buf.read_line(&mut v).unwrap(), 0); + assert_eq!(v, ""); +} + +#[test] +fn lines() { + let buf = Cursor::new(&b"12\r"[..]); + let mut s = buf.lines(); + assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string()); + assert!(s.next().is_none()); + + let buf = Cursor::new(&b"12\r\n\n"[..]); + let mut s = buf.lines(); + assert_eq!(s.next().unwrap().unwrap(), "12".to_string()); + assert_eq!(s.next().unwrap().unwrap(), "".to_string()); + assert!(s.next().is_none()); +} + +#[test] +fn read_to_end() { + let mut c = Cursor::new(&b""[..]); + let mut v = Vec::new(); + assert_eq!(c.read_to_end(&mut v).unwrap(), 0); + assert_eq!(v, []); + + let mut c = Cursor::new(&b"1"[..]); + let mut v = Vec::new(); + assert_eq!(c.read_to_end(&mut v).unwrap(), 1); + assert_eq!(v, b"1"); + + let cap = 1024 * 1024; + let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>(); + let mut v = Vec::new(); + let (a, b) = data.split_at(data.len() / 2); + assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len()); + assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len()); + assert_eq!(v, data); +} + +#[test] +fn read_to_string() { + let mut c = Cursor::new(&b""[..]); + let mut v = String::new(); + assert_eq!(c.read_to_string(&mut v).unwrap(), 0); + assert_eq!(v, ""); + + let mut c = Cursor::new(&b"1"[..]); + let mut v = String::new(); + assert_eq!(c.read_to_string(&mut v).unwrap(), 1); + assert_eq!(v, "1"); + + let mut c = Cursor::new(&b"\xff"[..]); + let mut v = String::new(); + assert!(c.read_to_string(&mut v).is_err()); +} + +#[test] +fn read_exact() { + let mut buf = [0; 4]; + + let mut c = Cursor::new(&b""[..]); + assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); + + let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..])); + c.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"1234"); + c.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"5678"); + assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); +} + +#[test] +fn read_exact_slice() { + let mut buf = [0; 4]; + + let mut c = &b""[..]; + assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); + + let mut c = &b"123"[..]; + assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); + // make sure the optimized (early returning) method is being used + assert_eq!(&buf, &[0; 4]); + + let mut c = &b"1234"[..]; + c.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"1234"); + + let mut c = &b"56789"[..]; + c.read_exact(&mut buf).unwrap(); + assert_eq!(&buf, b"5678"); + assert_eq!(c, b"9"); +} + +#[test] +fn take_eof() { + struct R; + + impl Read for R { + fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { + Err(io::Error::new(io::ErrorKind::Other, "")) + } + } + impl BufRead for R { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + Err(io::Error::new(io::ErrorKind::Other, "")) + } + fn consume(&mut self, _amt: usize) {} + } + + let mut buf = [0; 1]; + assert_eq!(0, R.take(0).read(&mut buf).unwrap()); + assert_eq!(b"", R.take(0).fill_buf().unwrap()); +} + +fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) { + let mut cat = Vec::new(); + loop { + let consume = { + let buf1 = br1.fill_buf().unwrap(); + let buf2 = br2.fill_buf().unwrap(); + let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() }; + assert_eq!(buf1[..minlen], buf2[..minlen]); + cat.extend_from_slice(&buf1[..minlen]); + minlen + }; + if consume == 0 { + break; + } + br1.consume(consume); + br2.consume(consume); + } + assert_eq!(br1.fill_buf().unwrap().len(), 0); + assert_eq!(br2.fill_buf().unwrap().len(), 0); + assert_eq!(&cat[..], &exp[..]) +} + +#[test] +fn chain_bufread() { + let testdata = b"ABCDEFGHIJKL"; + let chain1 = + (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]); + let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]); + cmp_bufread(chain1, chain2, &testdata[..]); +} + +#[test] +fn chain_zero_length_read_is_not_eof() { + let a = b"A"; + let b = b"B"; + let mut s = String::new(); + let mut chain = (&a[..]).chain(&b[..]); + chain.read(&mut []).unwrap(); + chain.read_to_string(&mut s).unwrap(); + assert_eq!("AB", s); +} + +#[bench] +#[cfg_attr(target_os = "emscripten", ignore)] +fn bench_read_to_end(b: &mut test::Bencher) { + b.iter(|| { + let mut lr = repeat(1).take(10000000); + let mut vec = Vec::with_capacity(1024); + super::read_to_end(&mut lr, &mut vec) + }); +} + +#[test] +fn seek_len() -> io::Result<()> { + let mut c = Cursor::new(vec![0; 15]); + assert_eq!(c.stream_len()?, 15); + + c.seek(SeekFrom::End(0))?; + let old_pos = c.stream_position()?; + assert_eq!(c.stream_len()?, 15); + assert_eq!(c.stream_position()?, old_pos); + + c.seek(SeekFrom::Start(7))?; + c.seek(SeekFrom::Current(2))?; + let old_pos = c.stream_position()?; + assert_eq!(c.stream_len()?, 15); + assert_eq!(c.stream_position()?, old_pos); + + Ok(()) +} + +#[test] +fn seek_position() -> io::Result<()> { + // All `asserts` are duplicated here to make sure the method does not + // change anything about the seek state. + let mut c = Cursor::new(vec![0; 15]); + assert_eq!(c.stream_position()?, 0); + assert_eq!(c.stream_position()?, 0); + + c.seek(SeekFrom::End(0))?; + assert_eq!(c.stream_position()?, 15); + assert_eq!(c.stream_position()?, 15); + + c.seek(SeekFrom::Start(7))?; + c.seek(SeekFrom::Current(2))?; + assert_eq!(c.stream_position()?, 9); + assert_eq!(c.stream_position()?, 9); + + c.seek(SeekFrom::End(-3))?; + c.seek(SeekFrom::Current(1))?; + c.seek(SeekFrom::Current(-5))?; + assert_eq!(c.stream_position()?, 8); + assert_eq!(c.stream_position()?, 8); + + Ok(()) +} + +// A simple example reader which uses the default implementation of +// read_to_end. +struct ExampleSliceReader<'a> { + slice: &'a [u8], +} + +impl<'a> Read for ExampleSliceReader<'a> { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + let len = cmp::min(self.slice.len(), buf.len()); + buf[..len].copy_from_slice(&self.slice[..len]); + self.slice = &self.slice[len..]; + Ok(len) + } +} + +#[test] +fn test_read_to_end_capacity() -> io::Result<()> { + let input = &b"foo"[..]; + + // read_to_end() generally needs to over-allocate, both for efficiency + // and so that it can distinguish EOF. Assert that this is the case + // with this simple ExampleSliceReader struct, which uses the default + // implementation of read_to_end. Even though vec1 is allocated with + // exactly enough capacity for the read, read_to_end will allocate more + // space here. + let mut vec1 = Vec::with_capacity(input.len()); + ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?; + assert_eq!(vec1.len(), input.len()); + assert!(vec1.capacity() > input.len(), "allocated more"); + + // However, std::io::Take includes an implementation of read_to_end + // that will not allocate when the limit has already been reached. In + // this case, vec2 never grows. + let mut vec2 = Vec::with_capacity(input.len()); + ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?; + assert_eq!(vec2.len(), input.len()); + assert_eq!(vec2.capacity(), input.len(), "did not allocate more"); + + Ok(()) +} + +#[test] +fn io_slice_mut_advance() { + let mut buf1 = [1; 8]; + let mut buf2 = [2; 16]; + let mut buf3 = [3; 8]; + let mut bufs = &mut [ + IoSliceMut::new(&mut buf1), + IoSliceMut::new(&mut buf2), + IoSliceMut::new(&mut buf3), + ][..]; + + // Only in a single buffer.. + bufs = IoSliceMut::advance(bufs, 1); + assert_eq!(bufs[0].deref(), [1; 7].as_ref()); + assert_eq!(bufs[1].deref(), [2; 16].as_ref()); + assert_eq!(bufs[2].deref(), [3; 8].as_ref()); + + // Removing a buffer, leaving others as is. + bufs = IoSliceMut::advance(bufs, 7); + assert_eq!(bufs[0].deref(), [2; 16].as_ref()); + assert_eq!(bufs[1].deref(), [3; 8].as_ref()); + + // Removing a buffer and removing from the next buffer. + bufs = IoSliceMut::advance(bufs, 18); + assert_eq!(bufs[0].deref(), [3; 6].as_ref()); +} + +#[test] +fn io_slice_mut_advance_empty_slice() { + let empty_bufs = &mut [][..]; + // Shouldn't panic. + IoSliceMut::advance(empty_bufs, 1); +} + +#[test] +fn io_slice_mut_advance_beyond_total_length() { + let mut buf1 = [1; 8]; + let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; + + // Going beyond the total length should be ok. + bufs = IoSliceMut::advance(bufs, 9); + assert!(bufs.is_empty()); +} + +#[test] +fn io_slice_advance() { + let buf1 = [1; 8]; + let buf2 = [2; 16]; + let buf3 = [3; 8]; + let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; + + // Only in a single buffer.. + bufs = IoSlice::advance(bufs, 1); + assert_eq!(bufs[0].deref(), [1; 7].as_ref()); + assert_eq!(bufs[1].deref(), [2; 16].as_ref()); + assert_eq!(bufs[2].deref(), [3; 8].as_ref()); + + // Removing a buffer, leaving others as is. + bufs = IoSlice::advance(bufs, 7); + assert_eq!(bufs[0].deref(), [2; 16].as_ref()); + assert_eq!(bufs[1].deref(), [3; 8].as_ref()); + + // Removing a buffer and removing from the next buffer. + bufs = IoSlice::advance(bufs, 18); + assert_eq!(bufs[0].deref(), [3; 6].as_ref()); +} + +#[test] +fn io_slice_advance_empty_slice() { + let empty_bufs = &mut [][..]; + // Shouldn't panic. + IoSlice::advance(empty_bufs, 1); +} + +#[test] +fn io_slice_advance_beyond_total_length() { + let buf1 = [1; 8]; + let mut bufs = &mut [IoSlice::new(&buf1)][..]; + + // Going beyond the total length should be ok. + bufs = IoSlice::advance(bufs, 9); + assert!(bufs.is_empty()); +} + +/// Create a new writer that reads from at most `n_bufs` and reads +/// `per_call` bytes (in total) per call to write. +fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter { + TestWriter { n_bufs, per_call, written: Vec::new() } +} + +struct TestWriter { + n_bufs: usize, + per_call: usize, + written: Vec<u8>, +} + +impl Write for TestWriter { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.write_vectored(&[IoSlice::new(buf)]) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let mut left = self.per_call; + let mut written = 0; + for buf in bufs.iter().take(self.n_bufs) { + let n = min(left, buf.len()); + self.written.extend_from_slice(&buf[0..n]); + left -= n; + written += n; + } + Ok(written) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[test] +fn test_writer_read_from_one_buf() { + let mut writer = test_writer(1, 2); + + assert_eq!(writer.write(&[]).unwrap(), 0); + assert_eq!(writer.write_vectored(&[]).unwrap(), 0); + + // Read at most 2 bytes. + assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2); + let bufs = &[IoSlice::new(&[2, 2, 2])]; + assert_eq!(writer.write_vectored(bufs).unwrap(), 2); + + // Only read from first buf. + let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])]; + assert_eq!(writer.write_vectored(bufs).unwrap(), 1); + + assert_eq!(writer.written, &[1, 1, 2, 2, 3]); +} + +#[test] +fn test_writer_read_from_multiple_bufs() { + let mut writer = test_writer(3, 3); + + // Read at most 3 bytes from two buffers. + let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; + assert_eq!(writer.write_vectored(bufs).unwrap(), 3); + + // Read at most 3 bytes from three buffers. + let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; + assert_eq!(writer.write_vectored(bufs).unwrap(), 3); + + assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]); +} + +#[test] +fn test_write_all_vectored() { + #[rustfmt::skip] // Becomes unreadable otherwise. + let tests: Vec<(_, &'static [u8])> = vec![ + (vec![], &[]), + (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), + (vec![IoSlice::new(&[1])], &[1]), + (vec![IoSlice::new(&[1, 2])], &[1, 2]), + (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), + (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), + (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), + (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), + (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]), + (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), + (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), + (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), + (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), + (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]), + (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), + (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), + (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), + (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]), + (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), + ]; + + let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]; + + for (n_bufs, per_call) in writer_configs.iter().copied() { + for (mut input, wanted) in tests.clone().into_iter() { + let mut writer = test_writer(n_bufs, per_call); + assert!(writer.write_all_vectored(&mut *input).is_ok()); + assert_eq!(&*writer.written, &*wanted); + } + } +} diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index a093b745b0c..44d2937ee1b 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -1,5 +1,8 @@ #![allow(missing_copy_implementations)] +#[cfg(test)] +mod tests; + use crate::fmt; use crate::io::{self, BufRead, ErrorKind, Initializer, IoSlice, IoSliceMut, Read, Write}; use crate::mem::MaybeUninit; @@ -49,24 +52,27 @@ where W: Write, { let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit(); - // FIXME(#53491): This is calling `get_mut` and `get_ref` on an uninitialized - // `MaybeUninit`. Revisit this once we decided whether that is valid or not. - // This is still technically undefined behavior due to creating a reference - // to uninitialized data, but within libstd we can rely on more guarantees - // than if this code were in an external lib. + // FIXME: #42788 + // + // - This creates a (mut) reference to a slice of + // _uninitialized_ integers, which is **undefined behavior** + // + // - Only the standard library gets to soundly "ignore" this, + // based on its privileged knowledge of unstable rustc + // internals; unsafe { - reader.initializer().initialize(buf.get_mut()); + reader.initializer().initialize(buf.assume_init_mut()); } let mut written = 0; loop { - let len = match reader.read(unsafe { buf.get_mut() }) { + let len = match reader.read(unsafe { buf.assume_init_mut() }) { Ok(0) => return Ok(written), Ok(len) => len, Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, Err(e) => return Err(e), }; - writer.write_all(unsafe { &buf.get_ref()[..len] })?; + writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?; written += len as u64; } } @@ -254,52 +260,3 @@ impl fmt::Debug for Sink { f.pad("Sink { .. }") } } - -#[cfg(test)] -mod tests { - use crate::io::prelude::*; - use crate::io::{copy, empty, repeat, sink}; - - #[test] - fn copy_copies() { - let mut r = repeat(0).take(4); - let mut w = sink(); - assert_eq!(copy(&mut r, &mut w).unwrap(), 4); - - let mut r = repeat(0).take(1 << 17); - assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17); - } - - #[test] - fn sink_sinks() { - let mut s = sink(); - assert_eq!(s.write(&[]).unwrap(), 0); - assert_eq!(s.write(&[0]).unwrap(), 1); - assert_eq!(s.write(&[0; 1024]).unwrap(), 1024); - assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024); - } - - #[test] - fn empty_reads() { - let mut e = empty(); - assert_eq!(e.read(&mut []).unwrap(), 0); - assert_eq!(e.read(&mut [0]).unwrap(), 0); - assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0); - assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0); - } - - #[test] - fn repeat_repeats() { - let mut r = repeat(4); - let mut b = [0; 1024]; - assert_eq!(r.read(&mut b).unwrap(), 1024); - assert!(b.iter().all(|b| *b == 4)); - } - - #[test] - fn take_some_bytes() { - assert_eq!(repeat(4).take(100).bytes().count(), 100); - assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4); - assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20); - } -} diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs new file mode 100644 index 00000000000..e5e32ecb405 --- /dev/null +++ b/library/std/src/io/util/tests.rs @@ -0,0 +1,45 @@ +use crate::io::prelude::*; +use crate::io::{copy, empty, repeat, sink}; + +#[test] +fn copy_copies() { + let mut r = repeat(0).take(4); + let mut w = sink(); + assert_eq!(copy(&mut r, &mut w).unwrap(), 4); + + let mut r = repeat(0).take(1 << 17); + assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17); +} + +#[test] +fn sink_sinks() { + let mut s = sink(); + assert_eq!(s.write(&[]).unwrap(), 0); + assert_eq!(s.write(&[0]).unwrap(), 1); + assert_eq!(s.write(&[0; 1024]).unwrap(), 1024); + assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024); +} + +#[test] +fn empty_reads() { + let mut e = empty(); + assert_eq!(e.read(&mut []).unwrap(), 0); + assert_eq!(e.read(&mut [0]).unwrap(), 0); + assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0); + assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0); +} + +#[test] +fn repeat_repeats() { + let mut r = repeat(4); + let mut b = [0; 1024]; + assert_eq!(r.read(&mut b).unwrap(), 1024); + assert!(b.iter().all(|b| *b == 4)); +} + +#[test] +fn take_some_bytes() { + assert_eq!(repeat(4).take(100).bytes().count(), 100); + assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4); + assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20); +} diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index af25c39fccf..54ce0e7b831 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -107,7 +107,7 @@ mod break_keyword {} /// Sometimes a certain value is used many times throughout a program, and it can become /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to /// make it a variable that gets carried around to each function that needs it. In these cases, the -/// `const` keyword provides a convenient alternative to code duplication. +/// `const` keyword provides a convenient alternative to code duplication: /// /// ```rust /// const THING: u32 = 0xABAD1DEA; @@ -115,10 +115,12 @@ mod break_keyword {} /// let foo = 123 + THING; /// ``` /// -/// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the -/// compiler figure it out. Any constant value can be defined in a const, which in practice happens -/// to be most things that would be reasonable to have a constant (barring `const fn`s). For -/// example, you can't have a File as a `const`. +/// Constants must be explicitly typed; unlike with `let`, you can't ignore their type and let the +/// compiler figure it out. Any constant value can be defined in a `const`, which in practice happens +/// to be most things that would be reasonable to have in a constant (barring `const fn`s). For +/// example, you can't have a [`File`] as a `const`. +/// +/// [`File`]: crate::fs::File /// /// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses /// all others in a Rust program. For example, if you wanted to define a constant string, it would @@ -128,7 +130,7 @@ mod break_keyword {} /// const WORDS: &'static str = "hello rust!"; /// ``` /// -/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static: +/// Thanks to static lifetime elision, you usually don't have to explicitly use `'static`: /// /// ```rust /// const WORDS: &str = "hello convenience!"; @@ -136,19 +138,19 @@ mod break_keyword {} /// /// `const` items looks remarkably similar to `static` items, which introduces some confusion as /// to which one should be used at which times. To put it simply, constants are inlined wherever -/// they're used, making using them identical to simply replacing the name of the const with its -/// value. Static variables on the other hand point to a single location in memory, which all +/// they're used, making using them identical to simply replacing the name of the `const` with its +/// value. Static variables, on the other hand, point to a single location in memory, which all /// accesses share. This means that, unlike with constants, they can't have destructors, and act as /// a single value across the entire codebase. /// -/// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE. +/// Constants, like statics, should always be in `SCREAMING_SNAKE_CASE`. /// /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const -/// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs. +/// T` and `*mut T`. More about `const` as used in raw pointers can be read at the Rust docs for the [pointer primitive]. /// -/// For more detail on `const`, see the [Rust Book] or the [Reference] +/// For more detail on `const`, see the [Rust Book] or the [Reference]. /// -/// [pointer]: primitive.pointer.html +/// [pointer primitive]: primitive.pointer.html /// [Rust Book]: /// ../book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants /// [Reference]: ../reference/items/constant-items.html diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs index d0f27df5185..845e9d76a77 100644 --- a/library/std/src/lazy.rs +++ b/library/std/src/lazy.rs @@ -1,5 +1,8 @@ //! Lazy values and one-time initialization of static data. +#[cfg(test)] +mod tests; + use crate::{ cell::{Cell, UnsafeCell}, fmt, @@ -376,13 +379,13 @@ impl<T> SyncOnceCell<T> { /// Safety: The value must be initialized unsafe fn get_unchecked(&self) -> &T { debug_assert!(self.is_initialized()); - (&*self.value.get()).get_ref() + (&*self.value.get()).assume_init_ref() } /// Safety: The value must be initialized unsafe fn get_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.is_initialized()); - (&mut *self.value.get()).get_mut() + (&mut *self.value.get()).assume_init_mut() } } @@ -506,333 +509,3 @@ impl<T: Default> Default for SyncLazy<T> { SyncLazy::new(T::default) } } - -#[cfg(test)] -mod tests { - use crate::{ - lazy::{Lazy, SyncLazy, SyncOnceCell}, - panic, - sync::{ - atomic::{AtomicUsize, Ordering::SeqCst}, - mpsc::channel, - Mutex, - }, - thread, - }; - - #[test] - fn lazy_default() { - static CALLED: AtomicUsize = AtomicUsize::new(0); - - struct Foo(u8); - impl Default for Foo { - fn default() -> Self { - CALLED.fetch_add(1, SeqCst); - Foo(42) - } - } - - let lazy: Lazy<Mutex<Foo>> = <_>::default(); - - assert_eq!(CALLED.load(SeqCst), 0); - - assert_eq!(lazy.lock().unwrap().0, 42); - assert_eq!(CALLED.load(SeqCst), 1); - - lazy.lock().unwrap().0 = 21; - - assert_eq!(lazy.lock().unwrap().0, 21); - assert_eq!(CALLED.load(SeqCst), 1); - } - - #[test] - fn lazy_poisoning() { - let x: Lazy<String> = Lazy::new(|| panic!("kaboom")); - for _ in 0..2 { - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| x.len())); - assert!(res.is_err()); - } - } - - fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R { - thread::spawn(f).join().unwrap() - } - - #[test] - fn sync_once_cell() { - static ONCE_CELL: SyncOnceCell<i32> = SyncOnceCell::new(); - - assert!(ONCE_CELL.get().is_none()); - - spawn_and_wait(|| { - ONCE_CELL.get_or_init(|| 92); - assert_eq!(ONCE_CELL.get(), Some(&92)); - }); - - ONCE_CELL.get_or_init(|| panic!("Kabom!")); - assert_eq!(ONCE_CELL.get(), Some(&92)); - } - - #[test] - fn sync_once_cell_get_mut() { - let mut c = SyncOnceCell::new(); - assert!(c.get_mut().is_none()); - c.set(90).unwrap(); - *c.get_mut().unwrap() += 2; - assert_eq!(c.get_mut(), Some(&mut 92)); - } - - #[test] - fn sync_once_cell_get_unchecked() { - let c = SyncOnceCell::new(); - c.set(92).unwrap(); - unsafe { - assert_eq!(c.get_unchecked(), &92); - } - } - - #[test] - fn sync_once_cell_drop() { - static DROP_CNT: AtomicUsize = AtomicUsize::new(0); - struct Dropper; - impl Drop for Dropper { - fn drop(&mut self) { - DROP_CNT.fetch_add(1, SeqCst); - } - } - - let x = SyncOnceCell::new(); - spawn_and_wait(move || { - x.get_or_init(|| Dropper); - assert_eq!(DROP_CNT.load(SeqCst), 0); - drop(x); - }); - - assert_eq!(DROP_CNT.load(SeqCst), 1); - } - - #[test] - fn sync_once_cell_drop_empty() { - let x = SyncOnceCell::<String>::new(); - drop(x); - } - - #[test] - fn clone() { - let s = SyncOnceCell::new(); - let c = s.clone(); - assert!(c.get().is_none()); - - s.set("hello".to_string()).unwrap(); - let c = s.clone(); - assert_eq!(c.get().map(String::as_str), Some("hello")); - } - - #[test] - fn get_or_try_init() { - let cell: SyncOnceCell<String> = SyncOnceCell::new(); - assert!(cell.get().is_none()); - - let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); - assert!(res.is_err()); - assert!(!cell.is_initialized()); - assert!(cell.get().is_none()); - - assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); - - assert_eq!( - cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), - Ok(&"hello".to_string()) - ); - assert_eq!(cell.get(), Some(&"hello".to_string())); - } - - #[test] - fn from_impl() { - assert_eq!(SyncOnceCell::from("value").get(), Some(&"value")); - assert_ne!(SyncOnceCell::from("foo").get(), Some(&"bar")); - } - - #[test] - fn partialeq_impl() { - assert!(SyncOnceCell::from("value") == SyncOnceCell::from("value")); - assert!(SyncOnceCell::from("foo") != SyncOnceCell::from("bar")); - - assert!(SyncOnceCell::<String>::new() == SyncOnceCell::new()); - assert!(SyncOnceCell::<String>::new() != SyncOnceCell::from("value".to_owned())); - } - - #[test] - fn into_inner() { - let cell: SyncOnceCell<String> = SyncOnceCell::new(); - assert_eq!(cell.into_inner(), None); - let cell = SyncOnceCell::new(); - cell.set("hello".to_string()).unwrap(); - assert_eq!(cell.into_inner(), Some("hello".to_string())); - } - - #[test] - fn sync_lazy_new() { - static CALLED: AtomicUsize = AtomicUsize::new(0); - static SYNC_LAZY: SyncLazy<i32> = SyncLazy::new(|| { - CALLED.fetch_add(1, SeqCst); - 92 - }); - - assert_eq!(CALLED.load(SeqCst), 0); - - spawn_and_wait(|| { - let y = *SYNC_LAZY - 30; - assert_eq!(y, 62); - assert_eq!(CALLED.load(SeqCst), 1); - }); - - let y = *SYNC_LAZY - 30; - assert_eq!(y, 62); - assert_eq!(CALLED.load(SeqCst), 1); - } - - #[test] - fn sync_lazy_default() { - static CALLED: AtomicUsize = AtomicUsize::new(0); - - struct Foo(u8); - impl Default for Foo { - fn default() -> Self { - CALLED.fetch_add(1, SeqCst); - Foo(42) - } - } - - let lazy: SyncLazy<Mutex<Foo>> = <_>::default(); - - assert_eq!(CALLED.load(SeqCst), 0); - - assert_eq!(lazy.lock().unwrap().0, 42); - assert_eq!(CALLED.load(SeqCst), 1); - - lazy.lock().unwrap().0 = 21; - - assert_eq!(lazy.lock().unwrap().0, 21); - assert_eq!(CALLED.load(SeqCst), 1); - } - - #[test] - fn static_sync_lazy() { - static XS: SyncLazy<Vec<i32>> = SyncLazy::new(|| { - let mut xs = Vec::new(); - xs.push(1); - xs.push(2); - xs.push(3); - xs - }); - - spawn_and_wait(|| { - assert_eq!(&*XS, &vec![1, 2, 3]); - }); - - assert_eq!(&*XS, &vec![1, 2, 3]); - } - - #[test] - fn static_sync_lazy_via_fn() { - fn xs() -> &'static Vec<i32> { - static XS: SyncOnceCell<Vec<i32>> = SyncOnceCell::new(); - XS.get_or_init(|| { - let mut xs = Vec::new(); - xs.push(1); - xs.push(2); - xs.push(3); - xs - }) - } - assert_eq!(xs(), &vec![1, 2, 3]); - } - - #[test] - fn sync_lazy_poisoning() { - let x: SyncLazy<String> = SyncLazy::new(|| panic!("kaboom")); - for _ in 0..2 { - let res = panic::catch_unwind(|| x.len()); - assert!(res.is_err()); - } - } - - #[test] - fn is_sync_send() { - fn assert_traits<T: Send + Sync>() {} - assert_traits::<SyncOnceCell<String>>(); - assert_traits::<SyncLazy<String>>(); - } - - #[test] - fn eval_once_macro() { - macro_rules! eval_once { - (|| -> $ty:ty { - $($body:tt)* - }) => {{ - static ONCE_CELL: SyncOnceCell<$ty> = SyncOnceCell::new(); - fn init() -> $ty { - $($body)* - } - ONCE_CELL.get_or_init(init) - }}; - } - - let fib: &'static Vec<i32> = eval_once! { - || -> Vec<i32> { - let mut res = vec![1, 1]; - for i in 0..10 { - let next = res[i] + res[i + 1]; - res.push(next); - } - res - } - }; - assert_eq!(fib[5], 8) - } - - #[test] - fn sync_once_cell_does_not_leak_partially_constructed_boxes() { - static ONCE_CELL: SyncOnceCell<String> = SyncOnceCell::new(); - - let n_readers = 10; - let n_writers = 3; - const MSG: &str = "Hello, World"; - - let (tx, rx) = channel(); - - for _ in 0..n_readers { - let tx = tx.clone(); - thread::spawn(move || { - loop { - if let Some(msg) = ONCE_CELL.get() { - tx.send(msg).unwrap(); - break; - } - #[cfg(target_env = "sgx")] - crate::thread::yield_now(); - } - }); - } - for _ in 0..n_writers { - thread::spawn(move || { - let _ = ONCE_CELL.set(MSG.to_owned()); - }); - } - - for _ in 0..n_readers { - let msg = rx.recv().unwrap(); - assert_eq!(msg, MSG); - } - } - - #[test] - fn dropck() { - let cell = SyncOnceCell::new(); - { - let s = String::new(); - cell.set(&s).unwrap(); - } - } -} diff --git a/library/std/src/lazy/tests.rs b/library/std/src/lazy/tests.rs new file mode 100644 index 00000000000..a170edbd997 --- /dev/null +++ b/library/std/src/lazy/tests.rs @@ -0,0 +1,323 @@ +use crate::{ + lazy::{Lazy, SyncLazy, SyncOnceCell}, + panic, + sync::{ + atomic::{AtomicUsize, Ordering::SeqCst}, + mpsc::channel, + Mutex, + }, + thread, +}; + +#[test] +fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy<Mutex<Foo>> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn lazy_poisoning() { + let x: Lazy<String> = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| x.len())); + assert!(res.is_err()); + } +} + +fn spawn_and_wait<R: Send + 'static>(f: impl FnOnce() -> R + Send + 'static) -> R { + thread::spawn(f).join().unwrap() +} + +#[test] +fn sync_once_cell() { + static ONCE_CELL: SyncOnceCell<i32> = SyncOnceCell::new(); + + assert!(ONCE_CELL.get().is_none()); + + spawn_and_wait(|| { + ONCE_CELL.get_or_init(|| 92); + assert_eq!(ONCE_CELL.get(), Some(&92)); + }); + + ONCE_CELL.get_or_init(|| panic!("Kabom!")); + assert_eq!(ONCE_CELL.get(), Some(&92)); +} + +#[test] +fn sync_once_cell_get_mut() { + let mut c = SyncOnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); +} + +#[test] +fn sync_once_cell_get_unchecked() { + let c = SyncOnceCell::new(); + c.set(92).unwrap(); + unsafe { + assert_eq!(c.get_unchecked(), &92); + } +} + +#[test] +fn sync_once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = SyncOnceCell::new(); + spawn_and_wait(move || { + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + }); + + assert_eq!(DROP_CNT.load(SeqCst), 1); +} + +#[test] +fn sync_once_cell_drop_empty() { + let x = SyncOnceCell::<String>::new(); + drop(x); +} + +#[test] +fn clone() { + let s = SyncOnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); +} + +#[test] +fn get_or_try_init() { + let cell: SyncOnceCell<String> = SyncOnceCell::new(); + assert!(cell.get().is_none()); + + let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + assert!(!cell.is_initialized()); + assert!(cell.get().is_none()); + + assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + + assert_eq!(cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), Ok(&"hello".to_string())); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[test] +fn from_impl() { + assert_eq!(SyncOnceCell::from("value").get(), Some(&"value")); + assert_ne!(SyncOnceCell::from("foo").get(), Some(&"bar")); +} + +#[test] +fn partialeq_impl() { + assert!(SyncOnceCell::from("value") == SyncOnceCell::from("value")); + assert!(SyncOnceCell::from("foo") != SyncOnceCell::from("bar")); + + assert!(SyncOnceCell::<String>::new() == SyncOnceCell::new()); + assert!(SyncOnceCell::<String>::new() != SyncOnceCell::from("value".to_owned())); +} + +#[test] +fn into_inner() { + let cell: SyncOnceCell<String> = SyncOnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = SyncOnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); +} + +#[test] +fn sync_lazy_new() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + static SYNC_LAZY: SyncLazy<i32> = SyncLazy::new(|| { + CALLED.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(CALLED.load(SeqCst), 0); + + spawn_and_wait(|| { + let y = *SYNC_LAZY - 30; + assert_eq!(y, 62); + assert_eq!(CALLED.load(SeqCst), 1); + }); + + let y = *SYNC_LAZY - 30; + assert_eq!(y, 62); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn sync_lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: SyncLazy<Mutex<Foo>> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn static_sync_lazy() { + static XS: SyncLazy<Vec<i32>> = SyncLazy::new(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }); + + spawn_and_wait(|| { + assert_eq!(&*XS, &vec![1, 2, 3]); + }); + + assert_eq!(&*XS, &vec![1, 2, 3]); +} + +#[test] +fn static_sync_lazy_via_fn() { + fn xs() -> &'static Vec<i32> { + static XS: SyncOnceCell<Vec<i32>> = SyncOnceCell::new(); + XS.get_or_init(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }) + } + assert_eq!(xs(), &vec![1, 2, 3]); +} + +#[test] +fn sync_lazy_poisoning() { + let x: SyncLazy<String> = SyncLazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } +} + +#[test] +fn is_sync_send() { + fn assert_traits<T: Send + Sync>() {} + assert_traits::<SyncOnceCell<String>>(); + assert_traits::<SyncLazy<String>>(); +} + +#[test] +fn eval_once_macro() { + macro_rules! eval_once { + (|| -> $ty:ty { + $($body:tt)* + }) => {{ + static ONCE_CELL: SyncOnceCell<$ty> = SyncOnceCell::new(); + fn init() -> $ty { + $($body)* + } + ONCE_CELL.get_or_init(init) + }}; + } + + let fib: &'static Vec<i32> = eval_once! { + || -> Vec<i32> { + let mut res = vec![1, 1]; + for i in 0..10 { + let next = res[i] + res[i + 1]; + res.push(next); + } + res + } + }; + assert_eq!(fib[5], 8) +} + +#[test] +fn sync_once_cell_does_not_leak_partially_constructed_boxes() { + static ONCE_CELL: SyncOnceCell<String> = SyncOnceCell::new(); + + let n_readers = 10; + let n_writers = 3; + const MSG: &str = "Hello, World"; + + let (tx, rx) = channel(); + + for _ in 0..n_readers { + let tx = tx.clone(); + thread::spawn(move || { + loop { + if let Some(msg) = ONCE_CELL.get() { + tx.send(msg).unwrap(); + break; + } + #[cfg(target_env = "sgx")] + crate::thread::yield_now(); + } + }); + } + for _ in 0..n_writers { + thread::spawn(move || { + let _ = ONCE_CELL.set(MSG.to_owned()); + }); + } + + for _ in 0..n_readers { + let msg = rx.recv().unwrap(); + assert_eq!(msg, MSG); + } +} + +#[test] +fn dropck() { + let cell = SyncOnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } +} diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 0797585e3df..dc57c1c1f44 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -238,7 +238,9 @@ #![feature(concat_idents)] #![feature(const_cstr_unchecked)] #![feature(const_fn_transmute)] +#![feature(const_ipv6)] #![feature(const_raw_ptr_deref)] +#![feature(const_ipv4)] #![feature(container_error_extra)] #![feature(core_intrinsics)] #![feature(custom_test_frameworks)] diff --git a/library/std/src/memchr.rs b/library/std/src/memchr.rs index d69294b2d20..86a08f75a8d 100644 --- a/library/std/src/memchr.rs +++ b/library/std/src/memchr.rs @@ -1,6 +1,9 @@ // Original implementation taken from rust-memchr. // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch +#[cfg(test)] +mod tests; + /// A safe interface to `memchr`. /// /// Returns the index corresponding to the first occurrence of `needle` in @@ -44,90 +47,3 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { crate::sys::memchr::memrchr(needle, haystack) } - -#[cfg(test)] -mod tests { - // test the implementations for the current platform - use super::{memchr, memrchr}; - - #[test] - fn matches_one() { - assert_eq!(Some(0), memchr(b'a', b"a")); - } - - #[test] - fn matches_begin() { - assert_eq!(Some(0), memchr(b'a', b"aaaa")); - } - - #[test] - fn matches_end() { - assert_eq!(Some(4), memchr(b'z', b"aaaaz")); - } - - #[test] - fn matches_nul() { - assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00")); - } - - #[test] - fn matches_past_nul() { - assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z")); - } - - #[test] - fn no_match_empty() { - assert_eq!(None, memchr(b'a', b"")); - } - - #[test] - fn no_match() { - assert_eq!(None, memchr(b'a', b"xyz")); - } - - #[test] - fn matches_one_reversed() { - assert_eq!(Some(0), memrchr(b'a', b"a")); - } - - #[test] - fn matches_begin_reversed() { - assert_eq!(Some(3), memrchr(b'a', b"aaaa")); - } - - #[test] - fn matches_end_reversed() { - assert_eq!(Some(0), memrchr(b'z', b"zaaaa")); - } - - #[test] - fn matches_nul_reversed() { - assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00")); - } - - #[test] - fn matches_past_nul_reversed() { - assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa")); - } - - #[test] - fn no_match_empty_reversed() { - assert_eq!(None, memrchr(b'a', b"")); - } - - #[test] - fn no_match_reversed() { - assert_eq!(None, memrchr(b'a', b"xyz")); - } - - #[test] - fn each_alignment() { - let mut data = [1u8; 64]; - let needle = 2; - let pos = 40; - data[pos] = needle; - for start in 0..16 { - assert_eq!(Some(pos - start), memchr(needle, &data[start..])); - } - } -} diff --git a/library/std/src/memchr/tests.rs b/library/std/src/memchr/tests.rs new file mode 100644 index 00000000000..557d749c7f6 --- /dev/null +++ b/library/std/src/memchr/tests.rs @@ -0,0 +1,86 @@ +// Original implementation taken from rust-memchr. +// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch + +// test the implementations for the current platform +use super::{memchr, memrchr}; + +#[test] +fn matches_one() { + assert_eq!(Some(0), memchr(b'a', b"a")); +} + +#[test] +fn matches_begin() { + assert_eq!(Some(0), memchr(b'a', b"aaaa")); +} + +#[test] +fn matches_end() { + assert_eq!(Some(4), memchr(b'z', b"aaaaz")); +} + +#[test] +fn matches_nul() { + assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00")); +} + +#[test] +fn matches_past_nul() { + assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z")); +} + +#[test] +fn no_match_empty() { + assert_eq!(None, memchr(b'a', b"")); +} + +#[test] +fn no_match() { + assert_eq!(None, memchr(b'a', b"xyz")); +} + +#[test] +fn matches_one_reversed() { + assert_eq!(Some(0), memrchr(b'a', b"a")); +} + +#[test] +fn matches_begin_reversed() { + assert_eq!(Some(3), memrchr(b'a', b"aaaa")); +} + +#[test] +fn matches_end_reversed() { + assert_eq!(Some(0), memrchr(b'z', b"zaaaa")); +} + +#[test] +fn matches_nul_reversed() { + assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00")); +} + +#[test] +fn matches_past_nul_reversed() { + assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa")); +} + +#[test] +fn no_match_empty_reversed() { + assert_eq!(None, memrchr(b'a', b"")); +} + +#[test] +fn no_match_reversed() { + assert_eq!(None, memrchr(b'a', b"xyz")); +} + +#[test] +fn each_alignment() { + let mut data = [1u8; 64]; + let needle = 2; + let pos = 40; + data[pos] = needle; + for start in 0..16 { + assert_eq!(Some(pos - start), memchr(needle, &data[start..])); + } +} diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs index d7d96862b21..499b1137dcb 100644 --- a/library/std/src/net/addr.rs +++ b/library/std/src/net/addr.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::cmp::Ordering; use crate::convert::TryInto; use crate::fmt; @@ -210,8 +213,6 @@ impl SocketAddr { /// /// [IP address]: IpAddr /// [`IPv4` address]: IpAddr::V4 - /// [`false`]: ../../std/primitive.bool.html - /// [`true`]: ../../std/primitive.bool.html /// /// # Examples /// @@ -232,8 +233,6 @@ impl SocketAddr { /// /// [IP address]: IpAddr /// [`IPv6` address]: IpAddr::V6 - /// [`false`]: ../../std/primitive.bool.html - /// [`true`]: ../../std/primitive.bool.html /// /// # Examples /// @@ -991,236 +990,3 @@ impl ToSocketAddrs for String { (&**self).to_socket_addrs() } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::net::test::{sa4, sa6, tsa}; - use crate::net::*; - - #[test] - fn to_socket_addr_ipaddr_u16() { - let a = Ipv4Addr::new(77, 88, 21, 11); - let p = 12345; - let e = SocketAddr::V4(SocketAddrV4::new(a, p)); - assert_eq!(Ok(vec![e]), tsa((a, p))); - } - - #[test] - fn to_socket_addr_str_u16() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); - - let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); - assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); - - let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); - #[cfg(not(target_env = "sgx"))] - assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); - #[cfg(target_env = "sgx")] - let _ = a; - } - - #[test] - fn to_socket_addr_str() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352")); - - let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); - assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); - - let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); - #[cfg(not(target_env = "sgx"))] - assert!(tsa("localhost:23924").unwrap().contains(&a)); - #[cfg(target_env = "sgx")] - let _ = a; - } - - #[test] - fn to_socket_addr_string() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352"))); - assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352"))); - assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352"))); - - let s = format!("{}:{}", "77.88.21.11", "24352"); - assert_eq!(Ok(vec![a]), tsa(s)); - // s has been moved into the tsa call - } - - #[test] - fn bind_udp_socket_bad() { - // rust-lang/rust#53957: This is a regression test for a parsing problem - // discovered as part of issue rust-lang/rust#23076, where we were - // incorrectly parsing invalid input and then that would result in a - // successful `UdpSocket` binding when we would expect failure. - // - // At one time, this test was written as a call to `tsa` with - // INPUT_23076. However, that structure yields an unreliable test, - // because it ends up passing junk input to the DNS server, and some DNS - // servers will respond with `Ok` to such input, with the ip address of - // the DNS server itself. - // - // This form of the test is more robust: even when the DNS server - // returns its own address, it is still an error to bind a UDP socket to - // a non-local address, and so we still get an error here in that case. - - const INPUT_23076: &'static str = "1200::AB00:1234::2552:7777:1313:34300"; - - assert!(crate::net::UdpSocket::bind(INPUT_23076).is_err()) - } - - #[test] - fn set_ip() { - fn ip4(low: u8) -> Ipv4Addr { - Ipv4Addr::new(77, 88, 21, low) - } - fn ip6(low: u16) -> Ipv6Addr { - Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, low) - } - - let mut v4 = SocketAddrV4::new(ip4(11), 80); - assert_eq!(v4.ip(), &ip4(11)); - v4.set_ip(ip4(12)); - assert_eq!(v4.ip(), &ip4(12)); - - let mut addr = SocketAddr::V4(v4); - assert_eq!(addr.ip(), IpAddr::V4(ip4(12))); - addr.set_ip(IpAddr::V4(ip4(13))); - assert_eq!(addr.ip(), IpAddr::V4(ip4(13))); - addr.set_ip(IpAddr::V6(ip6(14))); - assert_eq!(addr.ip(), IpAddr::V6(ip6(14))); - - let mut v6 = SocketAddrV6::new(ip6(1), 80, 0, 0); - assert_eq!(v6.ip(), &ip6(1)); - v6.set_ip(ip6(2)); - assert_eq!(v6.ip(), &ip6(2)); - - let mut addr = SocketAddr::V6(v6); - assert_eq!(addr.ip(), IpAddr::V6(ip6(2))); - addr.set_ip(IpAddr::V6(ip6(3))); - assert_eq!(addr.ip(), IpAddr::V6(ip6(3))); - addr.set_ip(IpAddr::V4(ip4(4))); - assert_eq!(addr.ip(), IpAddr::V4(ip4(4))); - } - - #[test] - fn set_port() { - let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80); - assert_eq!(v4.port(), 80); - v4.set_port(443); - assert_eq!(v4.port(), 443); - - let mut addr = SocketAddr::V4(v4); - assert_eq!(addr.port(), 443); - addr.set_port(8080); - assert_eq!(addr.port(), 8080); - - let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 0); - assert_eq!(v6.port(), 80); - v6.set_port(443); - assert_eq!(v6.port(), 443); - - let mut addr = SocketAddr::V6(v6); - assert_eq!(addr.port(), 443); - addr.set_port(8080); - assert_eq!(addr.port(), 8080); - } - - #[test] - fn set_flowinfo() { - let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0); - assert_eq!(v6.flowinfo(), 10); - v6.set_flowinfo(20); - assert_eq!(v6.flowinfo(), 20); - } - - #[test] - fn set_scope_id() { - let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 10); - assert_eq!(v6.scope_id(), 10); - v6.set_scope_id(20); - assert_eq!(v6.scope_id(), 20); - } - - #[test] - fn is_v4() { - let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)); - assert!(v4.is_ipv4()); - assert!(!v4.is_ipv6()); - } - - #[test] - fn is_v6() { - let v6 = SocketAddr::V6(SocketAddrV6::new( - Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), - 80, - 10, - 0, - )); - assert!(!v6.is_ipv4()); - assert!(v6.is_ipv6()); - } - - #[test] - fn socket_v4_to_str() { - let socket = SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 8080); - - assert_eq!(format!("{}", socket), "192.168.0.1:8080"); - assert_eq!(format!("{:<20}", socket), "192.168.0.1:8080 "); - assert_eq!(format!("{:>20}", socket), " 192.168.0.1:8080"); - assert_eq!(format!("{:^20}", socket), " 192.168.0.1:8080 "); - assert_eq!(format!("{:.10}", socket), "192.168.0."); - } - - #[test] - fn socket_v6_to_str() { - let socket: SocketAddrV6 = "[2a02:6b8:0:1::1]:53".parse().unwrap(); - - assert_eq!(format!("{}", socket), "[2a02:6b8:0:1::1]:53"); - assert_eq!(format!("{:<24}", socket), "[2a02:6b8:0:1::1]:53 "); - assert_eq!(format!("{:>24}", socket), " [2a02:6b8:0:1::1]:53"); - assert_eq!(format!("{:^24}", socket), " [2a02:6b8:0:1::1]:53 "); - assert_eq!(format!("{:.15}", socket), "[2a02:6b8:0:1::"); - } - - #[test] - fn compare() { - let v4_1 = "224.120.45.1:23456".parse::<SocketAddrV4>().unwrap(); - let v4_2 = "224.210.103.5:12345".parse::<SocketAddrV4>().unwrap(); - let v4_3 = "224.210.103.5:23456".parse::<SocketAddrV4>().unwrap(); - let v6_1 = "[2001:db8:f00::1002]:23456".parse::<SocketAddrV6>().unwrap(); - let v6_2 = "[2001:db8:f00::2001]:12345".parse::<SocketAddrV6>().unwrap(); - let v6_3 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap(); - - // equality - assert_eq!(v4_1, v4_1); - assert_eq!(v6_1, v6_1); - assert_eq!(SocketAddr::V4(v4_1), SocketAddr::V4(v4_1)); - assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1)); - assert!(v4_1 != v4_2); - assert!(v6_1 != v6_2); - - // compare different addresses - assert!(v4_1 < v4_2); - assert!(v6_1 < v6_2); - assert!(v4_2 > v4_1); - assert!(v6_2 > v6_1); - - // compare the same address with different ports - assert!(v4_2 < v4_3); - assert!(v6_2 < v6_3); - assert!(v4_3 > v4_2); - assert!(v6_3 > v6_2); - - // compare different addresses with the same port - assert!(v4_1 < v4_3); - assert!(v6_1 < v6_3); - assert!(v4_3 > v4_1); - assert!(v6_3 > v6_1); - - // compare with an inferred right-hand side - assert_eq!(v4_1, "224.120.45.1:23456".parse().unwrap()); - assert_eq!(v6_1, "[2001:db8:f00::1002]:23456".parse().unwrap()); - assert_eq!(SocketAddr::V4(v4_1), "224.120.45.1:23456".parse().unwrap()); - } -} diff --git a/library/std/src/net/addr/tests.rs b/library/std/src/net/addr/tests.rs new file mode 100644 index 00000000000..cee9087e13b --- /dev/null +++ b/library/std/src/net/addr/tests.rs @@ -0,0 +1,229 @@ +use crate::net::test::{sa4, sa6, tsa}; +use crate::net::*; + +#[test] +fn to_socket_addr_ipaddr_u16() { + let a = Ipv4Addr::new(77, 88, 21, 11); + let p = 12345; + let e = SocketAddr::V4(SocketAddrV4::new(a, p)); + assert_eq!(Ok(vec![e]), tsa((a, p))); +} + +#[test] +fn to_socket_addr_str_u16() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); + + let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); + assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); + + let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] + assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; +} + +#[test] +fn to_socket_addr_str() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352")); + + let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); + assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); + + let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] + assert!(tsa("localhost:23924").unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; +} + +#[test] +fn to_socket_addr_string() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352"))); + assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352"))); + assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352"))); + + let s = format!("{}:{}", "77.88.21.11", "24352"); + assert_eq!(Ok(vec![a]), tsa(s)); + // s has been moved into the tsa call +} + +#[test] +fn bind_udp_socket_bad() { + // rust-lang/rust#53957: This is a regression test for a parsing problem + // discovered as part of issue rust-lang/rust#23076, where we were + // incorrectly parsing invalid input and then that would result in a + // successful `UdpSocket` binding when we would expect failure. + // + // At one time, this test was written as a call to `tsa` with + // INPUT_23076. However, that structure yields an unreliable test, + // because it ends up passing junk input to the DNS server, and some DNS + // servers will respond with `Ok` to such input, with the ip address of + // the DNS server itself. + // + // This form of the test is more robust: even when the DNS server + // returns its own address, it is still an error to bind a UDP socket to + // a non-local address, and so we still get an error here in that case. + + const INPUT_23076: &'static str = "1200::AB00:1234::2552:7777:1313:34300"; + + assert!(crate::net::UdpSocket::bind(INPUT_23076).is_err()) +} + +#[test] +fn set_ip() { + fn ip4(low: u8) -> Ipv4Addr { + Ipv4Addr::new(77, 88, 21, low) + } + fn ip6(low: u16) -> Ipv6Addr { + Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, low) + } + + let mut v4 = SocketAddrV4::new(ip4(11), 80); + assert_eq!(v4.ip(), &ip4(11)); + v4.set_ip(ip4(12)); + assert_eq!(v4.ip(), &ip4(12)); + + let mut addr = SocketAddr::V4(v4); + assert_eq!(addr.ip(), IpAddr::V4(ip4(12))); + addr.set_ip(IpAddr::V4(ip4(13))); + assert_eq!(addr.ip(), IpAddr::V4(ip4(13))); + addr.set_ip(IpAddr::V6(ip6(14))); + assert_eq!(addr.ip(), IpAddr::V6(ip6(14))); + + let mut v6 = SocketAddrV6::new(ip6(1), 80, 0, 0); + assert_eq!(v6.ip(), &ip6(1)); + v6.set_ip(ip6(2)); + assert_eq!(v6.ip(), &ip6(2)); + + let mut addr = SocketAddr::V6(v6); + assert_eq!(addr.ip(), IpAddr::V6(ip6(2))); + addr.set_ip(IpAddr::V6(ip6(3))); + assert_eq!(addr.ip(), IpAddr::V6(ip6(3))); + addr.set_ip(IpAddr::V4(ip4(4))); + assert_eq!(addr.ip(), IpAddr::V4(ip4(4))); +} + +#[test] +fn set_port() { + let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80); + assert_eq!(v4.port(), 80); + v4.set_port(443); + assert_eq!(v4.port(), 443); + + let mut addr = SocketAddr::V4(v4); + assert_eq!(addr.port(), 443); + addr.set_port(8080); + assert_eq!(addr.port(), 8080); + + let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 0); + assert_eq!(v6.port(), 80); + v6.set_port(443); + assert_eq!(v6.port(), 443); + + let mut addr = SocketAddr::V6(v6); + assert_eq!(addr.port(), 443); + addr.set_port(8080); + assert_eq!(addr.port(), 8080); +} + +#[test] +fn set_flowinfo() { + let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0); + assert_eq!(v6.flowinfo(), 10); + v6.set_flowinfo(20); + assert_eq!(v6.flowinfo(), 20); +} + +#[test] +fn set_scope_id() { + let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 10); + assert_eq!(v6.scope_id(), 10); + v6.set_scope_id(20); + assert_eq!(v6.scope_id(), 20); +} + +#[test] +fn is_v4() { + let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)); + assert!(v4.is_ipv4()); + assert!(!v4.is_ipv6()); +} + +#[test] +fn is_v6() { + let v6 = SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), + 80, + 10, + 0, + )); + assert!(!v6.is_ipv4()); + assert!(v6.is_ipv6()); +} + +#[test] +fn socket_v4_to_str() { + let socket = SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 8080); + + assert_eq!(format!("{}", socket), "192.168.0.1:8080"); + assert_eq!(format!("{:<20}", socket), "192.168.0.1:8080 "); + assert_eq!(format!("{:>20}", socket), " 192.168.0.1:8080"); + assert_eq!(format!("{:^20}", socket), " 192.168.0.1:8080 "); + assert_eq!(format!("{:.10}", socket), "192.168.0."); +} + +#[test] +fn socket_v6_to_str() { + let socket: SocketAddrV6 = "[2a02:6b8:0:1::1]:53".parse().unwrap(); + + assert_eq!(format!("{}", socket), "[2a02:6b8:0:1::1]:53"); + assert_eq!(format!("{:<24}", socket), "[2a02:6b8:0:1::1]:53 "); + assert_eq!(format!("{:>24}", socket), " [2a02:6b8:0:1::1]:53"); + assert_eq!(format!("{:^24}", socket), " [2a02:6b8:0:1::1]:53 "); + assert_eq!(format!("{:.15}", socket), "[2a02:6b8:0:1::"); +} + +#[test] +fn compare() { + let v4_1 = "224.120.45.1:23456".parse::<SocketAddrV4>().unwrap(); + let v4_2 = "224.210.103.5:12345".parse::<SocketAddrV4>().unwrap(); + let v4_3 = "224.210.103.5:23456".parse::<SocketAddrV4>().unwrap(); + let v6_1 = "[2001:db8:f00::1002]:23456".parse::<SocketAddrV6>().unwrap(); + let v6_2 = "[2001:db8:f00::2001]:12345".parse::<SocketAddrV6>().unwrap(); + let v6_3 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap(); + + // equality + assert_eq!(v4_1, v4_1); + assert_eq!(v6_1, v6_1); + assert_eq!(SocketAddr::V4(v4_1), SocketAddr::V4(v4_1)); + assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1)); + assert!(v4_1 != v4_2); + assert!(v6_1 != v6_2); + + // compare different addresses + assert!(v4_1 < v4_2); + assert!(v6_1 < v6_2); + assert!(v4_2 > v4_1); + assert!(v6_2 > v6_1); + + // compare the same address with different ports + assert!(v4_2 < v4_3); + assert!(v6_2 < v6_3); + assert!(v4_3 > v4_2); + assert!(v6_3 > v6_2); + + // compare different addresses with the same port + assert!(v4_1 < v4_3); + assert!(v6_1 < v6_3); + assert!(v4_3 > v4_1); + assert!(v6_3 > v6_1); + + // compare with an inferred right-hand side + assert_eq!(v4_1, "224.120.45.1:23456".parse().unwrap()); + assert_eq!(v6_1, "[2001:db8:f00::1002]:23456".parse().unwrap()); + assert_eq!(SocketAddr::V4(v4_1), "224.120.45.1:23456".parse().unwrap()); +} diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 85bb6b60e68..e2fc7edb87e 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -6,6 +6,10 @@ issue = "27709" )] +// Tests for this module +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::cmp::Ordering; use crate::fmt::{self, Write as FmtWrite}; use crate::hash; @@ -136,8 +140,6 @@ impl IpAddr { /// See the documentation for [`Ipv4Addr::is_unspecified()`] and /// [`Ipv6Addr::is_unspecified()`] for more details. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -159,8 +161,6 @@ impl IpAddr { /// See the documentation for [`Ipv4Addr::is_loopback()`] and /// [`Ipv6Addr::is_loopback()`] for more details. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -182,8 +182,6 @@ impl IpAddr { /// See the documentation for [`Ipv4Addr::is_global()`] and /// [`Ipv6Addr::is_global()`] for more details. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -206,8 +204,6 @@ impl IpAddr { /// See the documentation for [`Ipv4Addr::is_multicast()`] and /// [`Ipv6Addr::is_multicast()`] for more details. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -229,8 +225,6 @@ impl IpAddr { /// See the documentation for [`Ipv4Addr::is_documentation()`] and /// [`Ipv6Addr::is_documentation()`] for more details. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -254,8 +248,6 @@ impl IpAddr { /// Returns [`true`] if this address is an [`IPv4` address], and [`false`] /// otherwise. /// - /// [`true`]: ../../std/primitive.bool.html - /// [`false`]: ../../std/primitive.bool.html /// [`IPv4` address]: IpAddr::V4 /// /// # Examples @@ -274,8 +266,6 @@ impl IpAddr { /// Returns [`true`] if this address is an [`IPv6` address], and [`false`] /// otherwise. /// - /// [`true`]: ../../std/primitive.bool.html - /// [`false`]: ../../std/primitive.bool.html /// [`IPv6` address]: IpAddr::V6 /// /// # Examples @@ -361,8 +351,9 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// assert_eq!(addr.octets(), [127, 0, 0, 1]); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn octets(&self) -> [u8; 4] { + pub const fn octets(&self) -> [u8; 4] { // This returns the order we want because s_addr is stored in big-endian. self.inner.s_addr.to_ne_bytes() } @@ -372,7 +363,6 @@ impl Ipv4Addr { /// This property is defined in _UNIX Network Programming, Second Edition_, /// W. Richard Stevens, p. 891; see also [ip7]. /// - /// [`true`]: ../../std/primitive.bool.html /// [ip7]: http://man7.org/linux/man-pages/man7/ip.7.html /// /// # Examples @@ -393,7 +383,6 @@ impl Ipv4Addr { /// /// This property is defined by [IETF RFC 1122]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122 /// /// # Examples @@ -404,8 +393,9 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_loopback(), true); /// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_loopback(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_loopback(&self) -> bool { + pub const fn is_loopback(&self) -> bool { self.octets()[0] == 127 } @@ -417,7 +407,6 @@ impl Ipv4Addr { /// - 172.16.0.0/12 /// - 192.168.0.0/16 /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918 /// /// # Examples @@ -433,8 +422,9 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(192, 168, 0, 2).is_private(), true); /// assert_eq!(Ipv4Addr::new(192, 169, 0, 2).is_private(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_private(&self) -> bool { + pub const fn is_private(&self) -> bool { match self.octets() { [10, ..] => true, [172, b, ..] if b >= 16 && b <= 31 => true, @@ -447,7 +437,6 @@ impl Ipv4Addr { /// /// This property is defined by [IETF RFC 3927]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 3927]: https://tools.ietf.org/html/rfc3927 /// /// # Examples @@ -459,8 +448,9 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(169, 254, 10, 65).is_link_local(), true); /// assert_eq!(Ipv4Addr::new(16, 89, 10, 65).is_link_local(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_link_local(&self) -> bool { + pub const fn is_link_local(&self) -> bool { match self.octets() { [169, 254, ..] => true, _ => false, @@ -486,8 +476,6 @@ impl Ipv4Addr { /// - addresses reserved for networking devices benchmarking (see /// [`Ipv4Addr::is_benchmarking()`]) /// - /// [`true`]: ../../std/primitive.bool.html - /// [`false`]: ../../std/primitive.bool.html /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml /// /// # Examples @@ -538,10 +526,13 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true); /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); /// ``` - pub fn is_global(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + pub const fn is_global(&self) -> bool { // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two // globally routable addresses in the 192.0.0.0/24 range. - if u32::from(*self) == 0xc0000009 || u32::from(*self) == 0xc000000a { + if u32::from_be_bytes(self.octets()) == 0xc0000009 + || u32::from_be_bytes(self.octets()) == 0xc000000a + { return true; } !self.is_private() @@ -560,7 +551,6 @@ impl Ipv4Addr { /// Returns [`true`] if this address is part of the Shared Address Space defined in /// [IETF RFC 6598] (`100.64.0.0/10`). /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 6598]: https://tools.ietf.org/html/rfc6598 /// /// # Examples @@ -573,7 +563,8 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(100, 127, 255, 255).is_shared(), true); /// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false); /// ``` - pub fn is_shared(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + pub const fn is_shared(&self) -> bool { self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000) } @@ -586,7 +577,6 @@ impl Ipv4Addr { /// - `192.0.0.9/32` is the "Port Control Protocol Anycast" (see [IETF RFC 7723]) /// - `192.0.0.10/32` is used for NAT traversal (see [IETF RFC 8155]) /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 6890]: https://tools.ietf.org/html/rfc6890 /// [IETF RFC 7600]: https://tools.ietf.org/html/rfc7600 /// [IETF RFC 7723]: https://tools.ietf.org/html/rfc7723 @@ -605,7 +595,8 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false); /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false); /// ``` - pub fn is_ietf_protocol_assignment(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + pub const fn is_ietf_protocol_assignment(&self) -> bool { self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0 } @@ -613,7 +604,6 @@ impl Ipv4Addr { /// network devices benchmarking. This range is defined in [IETF RFC 2544] as `192.18.0.0` /// through `198.19.255.255` but [errata 423] corrects it to `198.18.0.0/15`. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 2544]: https://tools.ietf.org/html/rfc2544 /// [errata 423]: https://www.rfc-editor.org/errata/eid423 /// @@ -628,7 +618,8 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking(), true); /// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false); /// ``` - pub fn is_benchmarking(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + pub const fn is_benchmarking(&self) -> bool { self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18 } @@ -637,7 +628,6 @@ impl Ipv4Addr { /// broadcast address `255.255.255.255`, but this implementation explicitly excludes it, since /// it is obviously not reserved for future use. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 1112]: https://tools.ietf.org/html/rfc1112 /// /// # Warning @@ -660,7 +650,8 @@ impl Ipv4Addr { /// // The broadcast address is not considered as reserved for future use by this implementation /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false); /// ``` - pub fn is_reserved(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + pub const fn is_reserved(&self) -> bool { self.octets()[0] & 240 == 240 && !self.is_broadcast() } @@ -669,7 +660,6 @@ impl Ipv4Addr { /// Multicast addresses have a most significant octet between 224 and 239, /// and is defined by [IETF RFC 5771]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771 /// /// # Examples @@ -681,8 +671,9 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_multicast(), true); /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_multicast(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_multicast(&self) -> bool { + pub const fn is_multicast(&self) -> bool { self.octets()[0] >= 224 && self.octets()[0] <= 239 } @@ -690,7 +681,6 @@ impl Ipv4Addr { /// /// A broadcast address has all octets set to 255 as defined in [IETF RFC 919]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919 /// /// # Examples @@ -701,9 +691,10 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_broadcast(), true); /// assert_eq!(Ipv4Addr::new(236, 168, 10, 65).is_broadcast(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_broadcast(&self) -> bool { - self == &Self::BROADCAST + pub const fn is_broadcast(&self) -> bool { + u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets()) } /// Returns [`true`] if this address is in a range designated for documentation. @@ -714,7 +705,6 @@ impl Ipv4Addr { /// - 198.51.100.0/24 (TEST-NET-2) /// - 203.0.113.0/24 (TEST-NET-3) /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737 /// /// # Examples @@ -727,8 +717,9 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_documentation(), true); /// assert_eq!(Ipv4Addr::new(193, 34, 17, 19).is_documentation(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_documentation(&self) -> bool { + pub const fn is_documentation(&self) -> bool { match self.octets() { [192, 0, 2, _] => true, [198, 51, 100, _] => true, @@ -741,6 +732,9 @@ impl Ipv4Addr { /// /// a.b.c.d becomes ::a.b.c.d /// + /// This isn't typically the method you want; these addresses don't typically + /// function on modern systems. Use `to_ipv6_mapped` instead. + /// /// [`IPv6` address]: Ipv6Addr /// /// # Examples @@ -753,10 +747,13 @@ impl Ipv4Addr { /// Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767) /// ); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_ipv6_compatible(&self) -> Ipv6Addr { + pub const fn to_ipv6_compatible(&self) -> Ipv6Addr { let [a, b, c, d] = self.octets(); - Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d]) + Ipv6Addr { + inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] }, + } } /// Converts this address to an IPv4-mapped [`IPv6` address]. @@ -773,10 +770,13 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(), /// Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767)); /// ``` + #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_ipv6_mapped(&self) -> Ipv6Addr { + pub const fn to_ipv6_mapped(&self) -> Ipv6Addr { let [a, b, c, d] = self.octets(); - Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d]) + Ipv6Addr { + inner: c::in6_addr { s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] }, + } } } @@ -1098,8 +1098,9 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(), /// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]); /// ``` + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn segments(&self) -> [u16; 8] { + pub const fn segments(&self) -> [u16; 8] { // All elements in `s6_addr` must be big endian. // SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`. let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.inner.s6_addr) }; @@ -1120,7 +1121,6 @@ impl Ipv6Addr { /// /// This property is defined in [IETF RFC 4291]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// /// # Examples @@ -1131,16 +1131,16 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true); /// ``` + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_unspecified(&self) -> bool { - self.segments() == [0, 0, 0, 0, 0, 0, 0, 0] + pub const fn is_unspecified(&self) -> bool { + u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets()) } /// Returns [`true`] if this is a loopback address (::1). /// /// This property is defined in [IETF RFC 4291]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// /// # Examples @@ -1151,9 +1151,10 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true); /// ``` + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_loopback(&self) -> bool { - self.segments() == [0, 0, 0, 0, 0, 0, 0, 1] + pub const fn is_loopback(&self) -> bool { + u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets()) } /// Returns [`true`] if the address appears to be globally routable. @@ -1164,9 +1165,6 @@ impl Ipv6Addr { /// - link-local and unique local unicast addresses /// - interface-, link-, realm-, admin- and site-local multicast addresses /// - /// [`true`]: ../../std/primitive.bool.html - /// [`false`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -1178,7 +1176,8 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true); /// ``` - pub fn is_global(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_global(&self) -> bool { match self.multicast_scope() { Some(Ipv6MulticastScope::Global) => true, None => self.is_unicast_global(), @@ -1192,8 +1191,6 @@ impl Ipv6Addr { /// /// [IETF RFC 4193]: https://tools.ietf.org/html/rfc4193 /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -1204,7 +1201,8 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false); /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true); /// ``` - pub fn is_unique_local(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 } @@ -1225,8 +1223,6 @@ impl Ipv6Addr { /// addresses such as `fe80:0:0:1::` or `fe81::` as unicast link-local addresses for example. /// If you need a less strict validation use [`Ipv6Addr::is_unicast_link_local()`] instead. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -1259,7 +1255,8 @@ impl Ipv6Addr { /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 - pub fn is_unicast_link_local_strict(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_unicast_link_local_strict(&self) -> bool { (self.segments()[0] & 0xffff) == 0xfe80 && (self.segments()[1] & 0xffff) == 0 && (self.segments()[2] & 0xffff) == 0 @@ -1284,8 +1281,6 @@ impl Ipv6Addr { /// If you need a strict validation fully compliant with the RFC, use /// [`Ipv6Addr::is_unicast_link_local_strict()`] instead. /// - /// [`true`]: ../../std/primitive.bool.html - /// /// # Examples /// /// ``` @@ -1316,7 +1311,8 @@ impl Ipv6Addr { /// /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 - pub fn is_unicast_link_local(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 } @@ -1331,7 +1327,6 @@ impl Ipv6Addr { /// +----------+-------------------------+----------------------------+ /// ``` /// - /// [`true`]: ../../std/primitive.bool.html /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7 /// /// # Examples @@ -1355,7 +1350,8 @@ impl Ipv6Addr { /// addresses. /// /// [RFC 3879]: https://tools.ietf.org/html/rfc3879 - pub fn is_unicast_site_local(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_unicast_site_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfec0 } @@ -1364,7 +1360,6 @@ impl Ipv6Addr { /// /// This property is defined in [IETF RFC 3849]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 3849]: https://tools.ietf.org/html/rfc3849 /// /// # Examples @@ -1377,7 +1372,8 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(), false); /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true); /// ``` - pub fn is_documentation(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_documentation(&self) -> bool { (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) } @@ -1399,7 +1395,6 @@ impl Ipv6Addr { /// Global Unicast). /// ``` /// - /// [`true`]: ../../std/primitive.bool.html /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7 /// /// # Examples @@ -1412,7 +1407,8 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true); /// ``` - pub fn is_unicast_global(&self) -> bool { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn is_unicast_global(&self) -> bool { !self.is_multicast() && !self.is_loopback() && !self.is_unicast_link_local() @@ -1436,7 +1432,8 @@ impl Ipv6Addr { /// ); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None); /// ``` - pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> { if self.is_multicast() { match self.segments()[0] & 0x000f { 1 => Some(Ipv6MulticastScope::InterfaceLocal), @@ -1457,7 +1454,6 @@ impl Ipv6Addr { /// /// This property is defined by [IETF RFC 4291]. /// - /// [`true`]: ../../std/primitive.bool.html /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// /// # Examples @@ -1468,8 +1464,9 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false); /// ``` + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[stable(since = "1.7.0", feature = "ip_17")] - pub fn is_multicast(&self) -> bool { + pub const fn is_multicast(&self) -> bool { (self.segments()[0] & 0xff00) == 0xff00 } @@ -1494,7 +1491,8 @@ impl Ipv6Addr { /// Some(Ipv4Addr::new(192, 10, 2, 255))); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None); /// ``` - pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> { + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> { match self.octets() { [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => { Some(Ipv4Addr::new(a, b, c, d)) @@ -1521,8 +1519,9 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(), /// Some(Ipv4Addr::new(0, 0, 0, 1))); /// ``` + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_ipv4(&self) -> Option<Ipv4Addr> { + pub const fn to_ipv4(&self) -> Option<Ipv4Addr> { if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() { let [a, b] = ab.to_be_bytes(); let [c, d] = cd.to_be_bytes(); @@ -1895,862 +1894,3 @@ impl From<[u16; 8]> for IpAddr { IpAddr::V6(Ipv6Addr::from(segments)) } } - -// Tests for this module -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::net::test::{sa4, sa6, tsa}; - use crate::net::*; - use crate::str::FromStr; - - #[test] - fn test_from_str_ipv4() { - assert_eq!(Ok(Ipv4Addr::new(127, 0, 0, 1)), "127.0.0.1".parse()); - assert_eq!(Ok(Ipv4Addr::new(255, 255, 255, 255)), "255.255.255.255".parse()); - assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse()); - - // out of range - let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok(); - assert_eq!(None, none); - // too short - let none: Option<Ipv4Addr> = "255.0.0".parse().ok(); - assert_eq!(None, none); - // too long - let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok(); - assert_eq!(None, none); - // no number between dots - let none: Option<Ipv4Addr> = "255.0..1".parse().ok(); - assert_eq!(None, none); - } - - #[test] - fn test_from_str_ipv6() { - assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse()); - assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse()); - - assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse()); - assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse()); - - assert_eq!( - Ok(Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)), - "2a02:6b8::11:11".parse() - ); - - // too long group - let none: Option<Ipv6Addr> = "::00000".parse().ok(); - assert_eq!(None, none); - // too short - let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok(); - assert_eq!(None, none); - // too long - let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok(); - assert_eq!(None, none); - // triple colon - let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok(); - assert_eq!(None, none); - // two double colons - let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok(); - assert_eq!(None, none); - // `::` indicating zero groups of zeros - let none: Option<Ipv6Addr> = "1:2:3:4::5:6:7:8".parse().ok(); - assert_eq!(None, none); - } - - #[test] - fn test_from_str_ipv4_in_ipv6() { - assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 545)), "::192.0.2.33".parse()); - assert_eq!( - Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)), - "::FFFF:192.0.2.33".parse() - ); - assert_eq!( - Ok(Ipv6Addr::new(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)), - "64:ff9b::192.0.2.33".parse() - ); - assert_eq!( - Ok(Ipv6Addr::new(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)), - "2001:db8:122:c000:2:2100:192.0.2.33".parse() - ); - - // colon after v4 - let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok(); - assert_eq!(None, none); - // not enough groups - let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok(); - assert_eq!(None, none); - // too many groups - let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok(); - assert_eq!(None, none); - } - - #[test] - fn test_from_str_socket_addr() { - assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse()); - assert_eq!( - Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)), - "77.88.21.11:80".parse() - ); - assert_eq!( - Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)), - "[2a02:6b8:0:1::1]:53".parse() - ); - assert_eq!( - Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53, 0, 0)), - "[2a02:6b8:0:1::1]:53".parse() - ); - assert_eq!( - Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)), - "[::127.0.0.1]:22".parse() - ); - assert_eq!( - Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22, 0, 0)), - "[::127.0.0.1]:22".parse() - ); - - // without port - let none: Option<SocketAddr> = "127.0.0.1".parse().ok(); - assert_eq!(None, none); - // without port - let none: Option<SocketAddr> = "127.0.0.1:".parse().ok(); - assert_eq!(None, none); - // wrong brackets around v4 - let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok(); - assert_eq!(None, none); - // port out of range - let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok(); - assert_eq!(None, none); - } - - #[test] - fn ipv4_addr_to_string() { - assert_eq!(Ipv4Addr::new(127, 0, 0, 1).to_string(), "127.0.0.1"); - // Short address - assert_eq!(Ipv4Addr::new(1, 1, 1, 1).to_string(), "1.1.1.1"); - // Long address - assert_eq!(Ipv4Addr::new(127, 127, 127, 127).to_string(), "127.127.127.127"); - - // Test padding - assert_eq!(&format!("{:16}", Ipv4Addr::new(1, 1, 1, 1)), "1.1.1.1 "); - assert_eq!(&format!("{:>16}", Ipv4Addr::new(1, 1, 1, 1)), " 1.1.1.1"); - } - - #[test] - fn ipv6_addr_to_string() { - // ipv4-mapped address - let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280); - assert_eq!(a1.to_string(), "::ffff:192.0.2.128"); - - // ipv4-compatible address - let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280); - assert_eq!(a1.to_string(), "::192.0.2.128"); - - // v6 address with no zero segments - assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(), "8:9:a:b:c:d:e:f"); - - // longest possible IPv6 length - assert_eq!( - Ipv6Addr::new(0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888) - .to_string(), - "1111:2222:3333:4444:5555:6666:7777:8888" - ); - // padding - assert_eq!( - &format!("{:20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)), - "1:2:3:4:5:6:7:8 " - ); - assert_eq!( - &format!("{:>20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)), - " 1:2:3:4:5:6:7:8" - ); - - // reduce a single run of zeros - assert_eq!( - "ae::ffff:102:304", - Ipv6Addr::new(0xae, 0, 0, 0, 0, 0xffff, 0x0102, 0x0304).to_string() - ); - - // don't reduce just a single zero segment - assert_eq!("1:2:3:4:5:6:0:8", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 0, 8).to_string()); - - // 'any' address - assert_eq!("::", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).to_string()); - - // loopback address - assert_eq!("::1", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_string()); - - // ends in zeros - assert_eq!("1::", Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0).to_string()); - - // two runs of zeros, second one is longer - assert_eq!("1:0:0:4::8", Ipv6Addr::new(1, 0, 0, 4, 0, 0, 0, 8).to_string()); - - // two runs of zeros, equal length - assert_eq!("1::4:5:0:0:8", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8).to_string()); - } - - #[test] - fn ipv4_to_ipv6() { - assert_eq!( - Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678), - Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_mapped() - ); - assert_eq!( - Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678), - Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_compatible() - ); - } - - #[test] - fn ipv6_to_ipv4_mapped() { - assert_eq!( - Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4_mapped(), - Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) - ); - assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4_mapped(), None); - } - - #[test] - fn ipv6_to_ipv4() { - assert_eq!( - Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4(), - Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) - ); - assert_eq!( - Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4(), - Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) - ); - assert_eq!(Ipv6Addr::new(0, 0, 1, 0, 0, 0, 0x1234, 0x5678).to_ipv4(), None); - } - - #[test] - fn ip_properties() { - macro_rules! ip { - ($s:expr) => { - IpAddr::from_str($s).unwrap() - }; - } - - macro_rules! check { - ($s:expr) => { - check!($s, 0); - }; - - ($s:expr, $mask:expr) => {{ - let unspec: u8 = 1 << 0; - let loopback: u8 = 1 << 1; - let global: u8 = 1 << 2; - let multicast: u8 = 1 << 3; - let doc: u8 = 1 << 4; - - if ($mask & unspec) == unspec { - assert!(ip!($s).is_unspecified()); - } else { - assert!(!ip!($s).is_unspecified()); - } - - if ($mask & loopback) == loopback { - assert!(ip!($s).is_loopback()); - } else { - assert!(!ip!($s).is_loopback()); - } - - if ($mask & global) == global { - assert!(ip!($s).is_global()); - } else { - assert!(!ip!($s).is_global()); - } - - if ($mask & multicast) == multicast { - assert!(ip!($s).is_multicast()); - } else { - assert!(!ip!($s).is_multicast()); - } - - if ($mask & doc) == doc { - assert!(ip!($s).is_documentation()); - } else { - assert!(!ip!($s).is_documentation()); - } - }}; - } - - let unspec: u8 = 1 << 0; - let loopback: u8 = 1 << 1; - let global: u8 = 1 << 2; - let multicast: u8 = 1 << 3; - let doc: u8 = 1 << 4; - - check!("0.0.0.0", unspec); - check!("0.0.0.1"); - check!("0.1.0.0"); - check!("10.9.8.7"); - check!("127.1.2.3", loopback); - check!("172.31.254.253"); - check!("169.254.253.242"); - check!("192.0.2.183", doc); - check!("192.1.2.183", global); - check!("192.168.254.253"); - check!("198.51.100.0", doc); - check!("203.0.113.0", doc); - check!("203.2.113.0", global); - check!("224.0.0.0", global | multicast); - check!("239.255.255.255", global | multicast); - check!("255.255.255.255"); - // make sure benchmarking addresses are not global - check!("198.18.0.0"); - check!("198.18.54.2"); - check!("198.19.255.255"); - // make sure addresses reserved for protocol assignment are not global - check!("192.0.0.0"); - check!("192.0.0.255"); - check!("192.0.0.100"); - // make sure reserved addresses are not global - check!("240.0.0.0"); - check!("251.54.1.76"); - check!("254.255.255.255"); - // make sure shared addresses are not global - check!("100.64.0.0"); - check!("100.127.255.255"); - check!("100.100.100.0"); - - check!("::", unspec); - check!("::1", loopback); - check!("::0.0.0.2", global); - check!("1::", global); - check!("fc00::"); - check!("fdff:ffff::"); - check!("fe80:ffff::"); - check!("febf:ffff::"); - check!("fec0::", global); - check!("ff01::", multicast); - check!("ff02::", multicast); - check!("ff03::", multicast); - check!("ff04::", multicast); - check!("ff05::", multicast); - check!("ff08::", multicast); - check!("ff0e::", global | multicast); - check!("2001:db8:85a3::8a2e:370:7334", doc); - check!("102:304:506:708:90a:b0c:d0e:f10", global); - } - - #[test] - fn ipv4_properties() { - macro_rules! ip { - ($s:expr) => { - Ipv4Addr::from_str($s).unwrap() - }; - } - - macro_rules! check { - ($s:expr) => { - check!($s, 0); - }; - - ($s:expr, $mask:expr) => {{ - let unspec: u16 = 1 << 0; - let loopback: u16 = 1 << 1; - let private: u16 = 1 << 2; - let link_local: u16 = 1 << 3; - let global: u16 = 1 << 4; - let multicast: u16 = 1 << 5; - let broadcast: u16 = 1 << 6; - let documentation: u16 = 1 << 7; - let benchmarking: u16 = 1 << 8; - let ietf_protocol_assignment: u16 = 1 << 9; - let reserved: u16 = 1 << 10; - let shared: u16 = 1 << 11; - - if ($mask & unspec) == unspec { - assert!(ip!($s).is_unspecified()); - } else { - assert!(!ip!($s).is_unspecified()); - } - - if ($mask & loopback) == loopback { - assert!(ip!($s).is_loopback()); - } else { - assert!(!ip!($s).is_loopback()); - } - - if ($mask & private) == private { - assert!(ip!($s).is_private()); - } else { - assert!(!ip!($s).is_private()); - } - - if ($mask & link_local) == link_local { - assert!(ip!($s).is_link_local()); - } else { - assert!(!ip!($s).is_link_local()); - } - - if ($mask & global) == global { - assert!(ip!($s).is_global()); - } else { - assert!(!ip!($s).is_global()); - } - - if ($mask & multicast) == multicast { - assert!(ip!($s).is_multicast()); - } else { - assert!(!ip!($s).is_multicast()); - } - - if ($mask & broadcast) == broadcast { - assert!(ip!($s).is_broadcast()); - } else { - assert!(!ip!($s).is_broadcast()); - } - - if ($mask & documentation) == documentation { - assert!(ip!($s).is_documentation()); - } else { - assert!(!ip!($s).is_documentation()); - } - - if ($mask & benchmarking) == benchmarking { - assert!(ip!($s).is_benchmarking()); - } else { - assert!(!ip!($s).is_benchmarking()); - } - - if ($mask & ietf_protocol_assignment) == ietf_protocol_assignment { - assert!(ip!($s).is_ietf_protocol_assignment()); - } else { - assert!(!ip!($s).is_ietf_protocol_assignment()); - } - - if ($mask & reserved) == reserved { - assert!(ip!($s).is_reserved()); - } else { - assert!(!ip!($s).is_reserved()); - } - - if ($mask & shared) == shared { - assert!(ip!($s).is_shared()); - } else { - assert!(!ip!($s).is_shared()); - } - }}; - } - - let unspec: u16 = 1 << 0; - let loopback: u16 = 1 << 1; - let private: u16 = 1 << 2; - let link_local: u16 = 1 << 3; - let global: u16 = 1 << 4; - let multicast: u16 = 1 << 5; - let broadcast: u16 = 1 << 6; - let documentation: u16 = 1 << 7; - let benchmarking: u16 = 1 << 8; - let ietf_protocol_assignment: u16 = 1 << 9; - let reserved: u16 = 1 << 10; - let shared: u16 = 1 << 11; - - check!("0.0.0.0", unspec); - check!("0.0.0.1"); - check!("0.1.0.0"); - check!("10.9.8.7", private); - check!("127.1.2.3", loopback); - check!("172.31.254.253", private); - check!("169.254.253.242", link_local); - check!("192.0.2.183", documentation); - check!("192.1.2.183", global); - check!("192.168.254.253", private); - check!("198.51.100.0", documentation); - check!("203.0.113.0", documentation); - check!("203.2.113.0", global); - check!("224.0.0.0", global | multicast); - check!("239.255.255.255", global | multicast); - check!("255.255.255.255", broadcast); - check!("198.18.0.0", benchmarking); - check!("198.18.54.2", benchmarking); - check!("198.19.255.255", benchmarking); - check!("192.0.0.0", ietf_protocol_assignment); - check!("192.0.0.255", ietf_protocol_assignment); - check!("192.0.0.100", ietf_protocol_assignment); - check!("240.0.0.0", reserved); - check!("251.54.1.76", reserved); - check!("254.255.255.255", reserved); - check!("100.64.0.0", shared); - check!("100.127.255.255", shared); - check!("100.100.100.0", shared); - } - - #[test] - fn ipv6_properties() { - macro_rules! ip { - ($s:expr) => { - Ipv6Addr::from_str($s).unwrap() - }; - } - - macro_rules! check { - ($s:expr, &[$($octet:expr),*], $mask:expr) => { - assert_eq!($s, ip!($s).to_string()); - let octets = &[$($octet),*]; - assert_eq!(&ip!($s).octets(), octets); - assert_eq!(Ipv6Addr::from(*octets), ip!($s)); - - let unspecified: u16 = 1 << 0; - let loopback: u16 = 1 << 1; - let unique_local: u16 = 1 << 2; - let global: u16 = 1 << 3; - let unicast_link_local: u16 = 1 << 4; - let unicast_link_local_strict: u16 = 1 << 5; - let unicast_site_local: u16 = 1 << 6; - let unicast_global: u16 = 1 << 7; - let documentation: u16 = 1 << 8; - let multicast_interface_local: u16 = 1 << 9; - let multicast_link_local: u16 = 1 << 10; - let multicast_realm_local: u16 = 1 << 11; - let multicast_admin_local: u16 = 1 << 12; - let multicast_site_local: u16 = 1 << 13; - let multicast_organization_local: u16 = 1 << 14; - let multicast_global: u16 = 1 << 15; - let multicast: u16 = multicast_interface_local - | multicast_admin_local - | multicast_global - | multicast_link_local - | multicast_realm_local - | multicast_site_local - | multicast_organization_local; - - if ($mask & unspecified) == unspecified { - assert!(ip!($s).is_unspecified()); - } else { - assert!(!ip!($s).is_unspecified()); - } - if ($mask & loopback) == loopback { - assert!(ip!($s).is_loopback()); - } else { - assert!(!ip!($s).is_loopback()); - } - if ($mask & unique_local) == unique_local { - assert!(ip!($s).is_unique_local()); - } else { - assert!(!ip!($s).is_unique_local()); - } - if ($mask & global) == global { - assert!(ip!($s).is_global()); - } else { - assert!(!ip!($s).is_global()); - } - if ($mask & unicast_link_local) == unicast_link_local { - assert!(ip!($s).is_unicast_link_local()); - } else { - assert!(!ip!($s).is_unicast_link_local()); - } - if ($mask & unicast_link_local_strict) == unicast_link_local_strict { - assert!(ip!($s).is_unicast_link_local_strict()); - } else { - assert!(!ip!($s).is_unicast_link_local_strict()); - } - if ($mask & unicast_site_local) == unicast_site_local { - assert!(ip!($s).is_unicast_site_local()); - } else { - assert!(!ip!($s).is_unicast_site_local()); - } - if ($mask & unicast_global) == unicast_global { - assert!(ip!($s).is_unicast_global()); - } else { - assert!(!ip!($s).is_unicast_global()); - } - if ($mask & documentation) == documentation { - assert!(ip!($s).is_documentation()); - } else { - assert!(!ip!($s).is_documentation()); - } - if ($mask & multicast) != 0 { - assert!(ip!($s).multicast_scope().is_some()); - assert!(ip!($s).is_multicast()); - } else { - assert!(ip!($s).multicast_scope().is_none()); - assert!(!ip!($s).is_multicast()); - } - if ($mask & multicast_interface_local) == multicast_interface_local { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::InterfaceLocal); - } - if ($mask & multicast_link_local) == multicast_link_local { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::LinkLocal); - } - if ($mask & multicast_realm_local) == multicast_realm_local { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::RealmLocal); - } - if ($mask & multicast_admin_local) == multicast_admin_local { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::AdminLocal); - } - if ($mask & multicast_site_local) == multicast_site_local { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::SiteLocal); - } - if ($mask & multicast_organization_local) == multicast_organization_local { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::OrganizationLocal); - } - if ($mask & multicast_global) == multicast_global { - assert_eq!(ip!($s).multicast_scope().unwrap(), - Ipv6MulticastScope::Global); - } - } - } - - let unspecified: u16 = 1 << 0; - let loopback: u16 = 1 << 1; - let unique_local: u16 = 1 << 2; - let global: u16 = 1 << 3; - let unicast_link_local: u16 = 1 << 4; - let unicast_link_local_strict: u16 = 1 << 5; - let unicast_site_local: u16 = 1 << 6; - let unicast_global: u16 = 1 << 7; - let documentation: u16 = 1 << 8; - let multicast_interface_local: u16 = 1 << 9; - let multicast_link_local: u16 = 1 << 10; - let multicast_realm_local: u16 = 1 << 11; - let multicast_admin_local: u16 = 1 << 12; - let multicast_site_local: u16 = 1 << 13; - let multicast_organization_local: u16 = 1 << 14; - let multicast_global: u16 = 1 << 15; - - check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified); - - check!("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], loopback); - - check!( - "::0.0.0.2", - &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], - global | unicast_global - ); - - check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global); - - check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local); - - check!( - "fdff:ffff::", - &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unique_local - ); - - check!( - "fe80:ffff::", - &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_link_local - ); - - check!( - "fe80::", - &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_link_local | unicast_link_local_strict - ); - - check!( - "febf:ffff::", - &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_link_local - ); - - check!( - "febf::", - &[0xfe, 0xbf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_link_local - ); - - check!( - "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", - &[ - 0xfe, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff - ], - unicast_link_local - ); - - check!( - "fe80::ffff:ffff:ffff:ffff", - &[ - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff - ], - unicast_link_local | unicast_link_local_strict - ); - - check!( - "fe80:0:0:1::", - &[0xfe, 0x80, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_link_local - ); - - check!( - "fec0::", - &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - unicast_site_local | unicast_global | global - ); - - check!( - "ff01::", - &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_interface_local - ); - - check!( - "ff02::", - &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_link_local - ); - - check!( - "ff03::", - &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_realm_local - ); - - check!( - "ff04::", - &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_admin_local - ); - - check!( - "ff05::", - &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_site_local - ); - - check!( - "ff08::", - &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_organization_local - ); - - check!( - "ff0e::", - &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - multicast_global | global - ); - - check!( - "2001:db8:85a3::8a2e:370:7334", - &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34], - documentation - ); - - check!( - "102:304:506:708:90a:b0c:d0e:f10", - &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], - global | unicast_global - ); - } - - #[test] - fn to_socket_addr_socketaddr() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345); - assert_eq!(Ok(vec![a]), tsa(a)); - } - - #[test] - fn test_ipv4_to_int() { - let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44); - assert_eq!(u32::from(a), 0x11223344); - } - - #[test] - fn test_int_to_ipv4() { - let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44); - assert_eq!(Ipv4Addr::from(0x11223344), a); - } - - #[test] - fn test_ipv6_to_int() { - let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11); - assert_eq!(u128::from(a), 0x112233445566778899aabbccddeeff11u128); - } - - #[test] - fn test_int_to_ipv6() { - let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11); - assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a); - } - - #[test] - fn ipv4_from_constructors() { - assert_eq!(Ipv4Addr::LOCALHOST, Ipv4Addr::new(127, 0, 0, 1)); - assert!(Ipv4Addr::LOCALHOST.is_loopback()); - assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0)); - assert!(Ipv4Addr::UNSPECIFIED.is_unspecified()); - assert_eq!(Ipv4Addr::BROADCAST, Ipv4Addr::new(255, 255, 255, 255)); - assert!(Ipv4Addr::BROADCAST.is_broadcast()); - } - - #[test] - fn ipv6_from_contructors() { - assert_eq!(Ipv6Addr::LOCALHOST, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); - assert!(Ipv6Addr::LOCALHOST.is_loopback()); - assert_eq!(Ipv6Addr::UNSPECIFIED, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); - assert!(Ipv6Addr::UNSPECIFIED.is_unspecified()); - } - - #[test] - fn ipv4_from_octets() { - assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1)) - } - - #[test] - fn ipv6_from_segments() { - let from_u16s = - Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]); - let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff); - assert_eq!(new, from_u16s); - } - - #[test] - fn ipv6_from_octets() { - let from_u16s = - Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]); - let from_u8s = Ipv6Addr::from([ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, - 0xee, 0xff, - ]); - assert_eq!(from_u16s, from_u8s); - } - - #[test] - fn cmp() { - let v41 = Ipv4Addr::new(100, 64, 3, 3); - let v42 = Ipv4Addr::new(192, 0, 2, 2); - let v61 = "2001:db8:f00::1002".parse::<Ipv6Addr>().unwrap(); - let v62 = "2001:db8:f00::2001".parse::<Ipv6Addr>().unwrap(); - assert!(v41 < v42); - assert!(v61 < v62); - - assert_eq!(v41, IpAddr::V4(v41)); - assert_eq!(v61, IpAddr::V6(v61)); - assert!(v41 != IpAddr::V4(v42)); - assert!(v61 != IpAddr::V6(v62)); - - assert!(v41 < IpAddr::V4(v42)); - assert!(v61 < IpAddr::V6(v62)); - assert!(IpAddr::V4(v41) < v42); - assert!(IpAddr::V6(v61) < v62); - - assert!(v41 < IpAddr::V6(v61)); - assert!(IpAddr::V4(v41) < v61); - } - - #[test] - fn is_v4() { - let ip = IpAddr::V4(Ipv4Addr::new(100, 64, 3, 3)); - assert!(ip.is_ipv4()); - assert!(!ip.is_ipv6()); - } - - #[test] - fn is_v6() { - let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678)); - assert!(!ip.is_ipv4()); - assert!(ip.is_ipv6()); - } -} diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs new file mode 100644 index 00000000000..a2fba4b4cca --- /dev/null +++ b/library/std/src/net/ip/tests.rs @@ -0,0 +1,811 @@ +use crate::net::test::{sa4, sa6, tsa}; +use crate::net::*; +use crate::str::FromStr; + +#[test] +fn test_from_str_ipv4() { + assert_eq!(Ok(Ipv4Addr::new(127, 0, 0, 1)), "127.0.0.1".parse()); + assert_eq!(Ok(Ipv4Addr::new(255, 255, 255, 255)), "255.255.255.255".parse()); + assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse()); + + // out of range + let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok(); + assert_eq!(None, none); + // too short + let none: Option<Ipv4Addr> = "255.0.0".parse().ok(); + assert_eq!(None, none); + // too long + let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok(); + assert_eq!(None, none); + // no number between dots + let none: Option<Ipv4Addr> = "255.0..1".parse().ok(); + assert_eq!(None, none); +} + +#[test] +fn test_from_str_ipv6() { + assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse()); + assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse()); + + assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse()); + assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse()); + + assert_eq!(Ok(Ipv6Addr::new(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)), "2a02:6b8::11:11".parse()); + + // too long group + let none: Option<Ipv6Addr> = "::00000".parse().ok(); + assert_eq!(None, none); + // too short + let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok(); + assert_eq!(None, none); + // too long + let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok(); + assert_eq!(None, none); + // triple colon + let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok(); + assert_eq!(None, none); + // two double colons + let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok(); + assert_eq!(None, none); + // `::` indicating zero groups of zeros + let none: Option<Ipv6Addr> = "1:2:3:4::5:6:7:8".parse().ok(); + assert_eq!(None, none); +} + +#[test] +fn test_from_str_ipv4_in_ipv6() { + assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 545)), "::192.0.2.33".parse()); + assert_eq!(Ok(Ipv6Addr::new(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)), "::FFFF:192.0.2.33".parse()); + assert_eq!( + Ok(Ipv6Addr::new(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)), + "64:ff9b::192.0.2.33".parse() + ); + assert_eq!( + Ok(Ipv6Addr::new(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)), + "2001:db8:122:c000:2:2100:192.0.2.33".parse() + ); + + // colon after v4 + let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok(); + assert_eq!(None, none); + // not enough groups + let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok(); + assert_eq!(None, none); + // too many groups + let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok(); + assert_eq!(None, none); +} + +#[test] +fn test_from_str_socket_addr() { + assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse()); + assert_eq!(Ok(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)), "77.88.21.11:80".parse()); + assert_eq!( + Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)), + "[2a02:6b8:0:1::1]:53".parse() + ); + assert_eq!( + Ok(SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53, 0, 0)), + "[2a02:6b8:0:1::1]:53".parse() + ); + assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)), "[::127.0.0.1]:22".parse()); + assert_eq!( + Ok(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22, 0, 0)), + "[::127.0.0.1]:22".parse() + ); + + // without port + let none: Option<SocketAddr> = "127.0.0.1".parse().ok(); + assert_eq!(None, none); + // without port + let none: Option<SocketAddr> = "127.0.0.1:".parse().ok(); + assert_eq!(None, none); + // wrong brackets around v4 + let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok(); + assert_eq!(None, none); + // port out of range + let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok(); + assert_eq!(None, none); +} + +#[test] +fn ipv4_addr_to_string() { + assert_eq!(Ipv4Addr::new(127, 0, 0, 1).to_string(), "127.0.0.1"); + // Short address + assert_eq!(Ipv4Addr::new(1, 1, 1, 1).to_string(), "1.1.1.1"); + // Long address + assert_eq!(Ipv4Addr::new(127, 127, 127, 127).to_string(), "127.127.127.127"); + + // Test padding + assert_eq!(&format!("{:16}", Ipv4Addr::new(1, 1, 1, 1)), "1.1.1.1 "); + assert_eq!(&format!("{:>16}", Ipv4Addr::new(1, 1, 1, 1)), " 1.1.1.1"); +} + +#[test] +fn ipv6_addr_to_string() { + // ipv4-mapped address + let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280); + assert_eq!(a1.to_string(), "::ffff:192.0.2.128"); + + // ipv4-compatible address + let a1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x280); + assert_eq!(a1.to_string(), "::192.0.2.128"); + + // v6 address with no zero segments + assert_eq!(Ipv6Addr::new(8, 9, 10, 11, 12, 13, 14, 15).to_string(), "8:9:a:b:c:d:e:f"); + + // longest possible IPv6 length + assert_eq!( + Ipv6Addr::new(0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888).to_string(), + "1111:2222:3333:4444:5555:6666:7777:8888" + ); + // padding + assert_eq!(&format!("{:20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)), "1:2:3:4:5:6:7:8 "); + assert_eq!(&format!("{:>20}", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8)), " 1:2:3:4:5:6:7:8"); + + // reduce a single run of zeros + assert_eq!( + "ae::ffff:102:304", + Ipv6Addr::new(0xae, 0, 0, 0, 0, 0xffff, 0x0102, 0x0304).to_string() + ); + + // don't reduce just a single zero segment + assert_eq!("1:2:3:4:5:6:0:8", Ipv6Addr::new(1, 2, 3, 4, 5, 6, 0, 8).to_string()); + + // 'any' address + assert_eq!("::", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).to_string()); + + // loopback address + assert_eq!("::1", Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_string()); + + // ends in zeros + assert_eq!("1::", Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0).to_string()); + + // two runs of zeros, second one is longer + assert_eq!("1:0:0:4::8", Ipv6Addr::new(1, 0, 0, 4, 0, 0, 0, 8).to_string()); + + // two runs of zeros, equal length + assert_eq!("1::4:5:0:0:8", Ipv6Addr::new(1, 0, 0, 4, 5, 0, 0, 8).to_string()); +} + +#[test] +fn ipv4_to_ipv6() { + assert_eq!( + Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678), + Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_mapped() + ); + assert_eq!( + Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678), + Ipv4Addr::new(0x12, 0x34, 0x56, 0x78).to_ipv6_compatible() + ); +} + +#[test] +fn ipv6_to_ipv4_mapped() { + assert_eq!( + Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4_mapped(), + Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) + ); + assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4_mapped(), None); +} + +#[test] +fn ipv6_to_ipv4() { + assert_eq!( + Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678).to_ipv4(), + Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) + ); + assert_eq!( + Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x1234, 0x5678).to_ipv4(), + Some(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78)) + ); + assert_eq!(Ipv6Addr::new(0, 0, 1, 0, 0, 0, 0x1234, 0x5678).to_ipv4(), None); +} + +#[test] +fn ip_properties() { + macro_rules! ip { + ($s:expr) => { + IpAddr::from_str($s).unwrap() + }; + } + + macro_rules! check { + ($s:expr) => { + check!($s, 0); + }; + + ($s:expr, $mask:expr) => {{ + let unspec: u8 = 1 << 0; + let loopback: u8 = 1 << 1; + let global: u8 = 1 << 2; + let multicast: u8 = 1 << 3; + let doc: u8 = 1 << 4; + + if ($mask & unspec) == unspec { + assert!(ip!($s).is_unspecified()); + } else { + assert!(!ip!($s).is_unspecified()); + } + + if ($mask & loopback) == loopback { + assert!(ip!($s).is_loopback()); + } else { + assert!(!ip!($s).is_loopback()); + } + + if ($mask & global) == global { + assert!(ip!($s).is_global()); + } else { + assert!(!ip!($s).is_global()); + } + + if ($mask & multicast) == multicast { + assert!(ip!($s).is_multicast()); + } else { + assert!(!ip!($s).is_multicast()); + } + + if ($mask & doc) == doc { + assert!(ip!($s).is_documentation()); + } else { + assert!(!ip!($s).is_documentation()); + } + }}; + } + + let unspec: u8 = 1 << 0; + let loopback: u8 = 1 << 1; + let global: u8 = 1 << 2; + let multicast: u8 = 1 << 3; + let doc: u8 = 1 << 4; + + check!("0.0.0.0", unspec); + check!("0.0.0.1"); + check!("0.1.0.0"); + check!("10.9.8.7"); + check!("127.1.2.3", loopback); + check!("172.31.254.253"); + check!("169.254.253.242"); + check!("192.0.2.183", doc); + check!("192.1.2.183", global); + check!("192.168.254.253"); + check!("198.51.100.0", doc); + check!("203.0.113.0", doc); + check!("203.2.113.0", global); + check!("224.0.0.0", global | multicast); + check!("239.255.255.255", global | multicast); + check!("255.255.255.255"); + // make sure benchmarking addresses are not global + check!("198.18.0.0"); + check!("198.18.54.2"); + check!("198.19.255.255"); + // make sure addresses reserved for protocol assignment are not global + check!("192.0.0.0"); + check!("192.0.0.255"); + check!("192.0.0.100"); + // make sure reserved addresses are not global + check!("240.0.0.0"); + check!("251.54.1.76"); + check!("254.255.255.255"); + // make sure shared addresses are not global + check!("100.64.0.0"); + check!("100.127.255.255"); + check!("100.100.100.0"); + + check!("::", unspec); + check!("::1", loopback); + check!("::0.0.0.2", global); + check!("1::", global); + check!("fc00::"); + check!("fdff:ffff::"); + check!("fe80:ffff::"); + check!("febf:ffff::"); + check!("fec0::", global); + check!("ff01::", multicast); + check!("ff02::", multicast); + check!("ff03::", multicast); + check!("ff04::", multicast); + check!("ff05::", multicast); + check!("ff08::", multicast); + check!("ff0e::", global | multicast); + check!("2001:db8:85a3::8a2e:370:7334", doc); + check!("102:304:506:708:90a:b0c:d0e:f10", global); +} + +#[test] +fn ipv4_properties() { + macro_rules! ip { + ($s:expr) => { + Ipv4Addr::from_str($s).unwrap() + }; + } + + macro_rules! check { + ($s:expr) => { + check!($s, 0); + }; + + ($s:expr, $mask:expr) => {{ + let unspec: u16 = 1 << 0; + let loopback: u16 = 1 << 1; + let private: u16 = 1 << 2; + let link_local: u16 = 1 << 3; + let global: u16 = 1 << 4; + let multicast: u16 = 1 << 5; + let broadcast: u16 = 1 << 6; + let documentation: u16 = 1 << 7; + let benchmarking: u16 = 1 << 8; + let ietf_protocol_assignment: u16 = 1 << 9; + let reserved: u16 = 1 << 10; + let shared: u16 = 1 << 11; + + if ($mask & unspec) == unspec { + assert!(ip!($s).is_unspecified()); + } else { + assert!(!ip!($s).is_unspecified()); + } + + if ($mask & loopback) == loopback { + assert!(ip!($s).is_loopback()); + } else { + assert!(!ip!($s).is_loopback()); + } + + if ($mask & private) == private { + assert!(ip!($s).is_private()); + } else { + assert!(!ip!($s).is_private()); + } + + if ($mask & link_local) == link_local { + assert!(ip!($s).is_link_local()); + } else { + assert!(!ip!($s).is_link_local()); + } + + if ($mask & global) == global { + assert!(ip!($s).is_global()); + } else { + assert!(!ip!($s).is_global()); + } + + if ($mask & multicast) == multicast { + assert!(ip!($s).is_multicast()); + } else { + assert!(!ip!($s).is_multicast()); + } + + if ($mask & broadcast) == broadcast { + assert!(ip!($s).is_broadcast()); + } else { + assert!(!ip!($s).is_broadcast()); + } + + if ($mask & documentation) == documentation { + assert!(ip!($s).is_documentation()); + } else { + assert!(!ip!($s).is_documentation()); + } + + if ($mask & benchmarking) == benchmarking { + assert!(ip!($s).is_benchmarking()); + } else { + assert!(!ip!($s).is_benchmarking()); + } + + if ($mask & ietf_protocol_assignment) == ietf_protocol_assignment { + assert!(ip!($s).is_ietf_protocol_assignment()); + } else { + assert!(!ip!($s).is_ietf_protocol_assignment()); + } + + if ($mask & reserved) == reserved { + assert!(ip!($s).is_reserved()); + } else { + assert!(!ip!($s).is_reserved()); + } + + if ($mask & shared) == shared { + assert!(ip!($s).is_shared()); + } else { + assert!(!ip!($s).is_shared()); + } + }}; + } + + let unspec: u16 = 1 << 0; + let loopback: u16 = 1 << 1; + let private: u16 = 1 << 2; + let link_local: u16 = 1 << 3; + let global: u16 = 1 << 4; + let multicast: u16 = 1 << 5; + let broadcast: u16 = 1 << 6; + let documentation: u16 = 1 << 7; + let benchmarking: u16 = 1 << 8; + let ietf_protocol_assignment: u16 = 1 << 9; + let reserved: u16 = 1 << 10; + let shared: u16 = 1 << 11; + + check!("0.0.0.0", unspec); + check!("0.0.0.1"); + check!("0.1.0.0"); + check!("10.9.8.7", private); + check!("127.1.2.3", loopback); + check!("172.31.254.253", private); + check!("169.254.253.242", link_local); + check!("192.0.2.183", documentation); + check!("192.1.2.183", global); + check!("192.168.254.253", private); + check!("198.51.100.0", documentation); + check!("203.0.113.0", documentation); + check!("203.2.113.0", global); + check!("224.0.0.0", global | multicast); + check!("239.255.255.255", global | multicast); + check!("255.255.255.255", broadcast); + check!("198.18.0.0", benchmarking); + check!("198.18.54.2", benchmarking); + check!("198.19.255.255", benchmarking); + check!("192.0.0.0", ietf_protocol_assignment); + check!("192.0.0.255", ietf_protocol_assignment); + check!("192.0.0.100", ietf_protocol_assignment); + check!("240.0.0.0", reserved); + check!("251.54.1.76", reserved); + check!("254.255.255.255", reserved); + check!("100.64.0.0", shared); + check!("100.127.255.255", shared); + check!("100.100.100.0", shared); +} + +#[test] +fn ipv6_properties() { + macro_rules! ip { + ($s:expr) => { + Ipv6Addr::from_str($s).unwrap() + }; + } + + macro_rules! check { + ($s:expr, &[$($octet:expr),*], $mask:expr) => { + assert_eq!($s, ip!($s).to_string()); + let octets = &[$($octet),*]; + assert_eq!(&ip!($s).octets(), octets); + assert_eq!(Ipv6Addr::from(*octets), ip!($s)); + + let unspecified: u16 = 1 << 0; + let loopback: u16 = 1 << 1; + let unique_local: u16 = 1 << 2; + let global: u16 = 1 << 3; + let unicast_link_local: u16 = 1 << 4; + let unicast_link_local_strict: u16 = 1 << 5; + let unicast_site_local: u16 = 1 << 6; + let unicast_global: u16 = 1 << 7; + let documentation: u16 = 1 << 8; + let multicast_interface_local: u16 = 1 << 9; + let multicast_link_local: u16 = 1 << 10; + let multicast_realm_local: u16 = 1 << 11; + let multicast_admin_local: u16 = 1 << 12; + let multicast_site_local: u16 = 1 << 13; + let multicast_organization_local: u16 = 1 << 14; + let multicast_global: u16 = 1 << 15; + let multicast: u16 = multicast_interface_local + | multicast_admin_local + | multicast_global + | multicast_link_local + | multicast_realm_local + | multicast_site_local + | multicast_organization_local; + + if ($mask & unspecified) == unspecified { + assert!(ip!($s).is_unspecified()); + } else { + assert!(!ip!($s).is_unspecified()); + } + if ($mask & loopback) == loopback { + assert!(ip!($s).is_loopback()); + } else { + assert!(!ip!($s).is_loopback()); + } + if ($mask & unique_local) == unique_local { + assert!(ip!($s).is_unique_local()); + } else { + assert!(!ip!($s).is_unique_local()); + } + if ($mask & global) == global { + assert!(ip!($s).is_global()); + } else { + assert!(!ip!($s).is_global()); + } + if ($mask & unicast_link_local) == unicast_link_local { + assert!(ip!($s).is_unicast_link_local()); + } else { + assert!(!ip!($s).is_unicast_link_local()); + } + if ($mask & unicast_link_local_strict) == unicast_link_local_strict { + assert!(ip!($s).is_unicast_link_local_strict()); + } else { + assert!(!ip!($s).is_unicast_link_local_strict()); + } + if ($mask & unicast_site_local) == unicast_site_local { + assert!(ip!($s).is_unicast_site_local()); + } else { + assert!(!ip!($s).is_unicast_site_local()); + } + if ($mask & unicast_global) == unicast_global { + assert!(ip!($s).is_unicast_global()); + } else { + assert!(!ip!($s).is_unicast_global()); + } + if ($mask & documentation) == documentation { + assert!(ip!($s).is_documentation()); + } else { + assert!(!ip!($s).is_documentation()); + } + if ($mask & multicast) != 0 { + assert!(ip!($s).multicast_scope().is_some()); + assert!(ip!($s).is_multicast()); + } else { + assert!(ip!($s).multicast_scope().is_none()); + assert!(!ip!($s).is_multicast()); + } + if ($mask & multicast_interface_local) == multicast_interface_local { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::InterfaceLocal); + } + if ($mask & multicast_link_local) == multicast_link_local { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::LinkLocal); + } + if ($mask & multicast_realm_local) == multicast_realm_local { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::RealmLocal); + } + if ($mask & multicast_admin_local) == multicast_admin_local { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::AdminLocal); + } + if ($mask & multicast_site_local) == multicast_site_local { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::SiteLocal); + } + if ($mask & multicast_organization_local) == multicast_organization_local { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::OrganizationLocal); + } + if ($mask & multicast_global) == multicast_global { + assert_eq!(ip!($s).multicast_scope().unwrap(), + Ipv6MulticastScope::Global); + } + } + } + + let unspecified: u16 = 1 << 0; + let loopback: u16 = 1 << 1; + let unique_local: u16 = 1 << 2; + let global: u16 = 1 << 3; + let unicast_link_local: u16 = 1 << 4; + let unicast_link_local_strict: u16 = 1 << 5; + let unicast_site_local: u16 = 1 << 6; + let unicast_global: u16 = 1 << 7; + let documentation: u16 = 1 << 8; + let multicast_interface_local: u16 = 1 << 9; + let multicast_link_local: u16 = 1 << 10; + let multicast_realm_local: u16 = 1 << 11; + let multicast_admin_local: u16 = 1 << 12; + let multicast_site_local: u16 = 1 << 13; + let multicast_organization_local: u16 = 1 << 14; + let multicast_global: u16 = 1 << 15; + + check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified); + + check!("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], loopback); + + check!("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], global | unicast_global); + + check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global); + + check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local); + + check!( + "fdff:ffff::", + &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + unique_local + ); + + check!( + "fe80:ffff::", + &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + unicast_link_local + ); + + check!( + "fe80::", + &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + unicast_link_local | unicast_link_local_strict + ); + + check!( + "febf:ffff::", + &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + unicast_link_local + ); + + check!("febf::", &[0xfe, 0xbf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_link_local); + + check!( + "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", + &[ + 0xfe, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff + ], + unicast_link_local + ); + + check!( + "fe80::ffff:ffff:ffff:ffff", + &[ + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff + ], + unicast_link_local | unicast_link_local_strict + ); + + check!( + "fe80:0:0:1::", + &[0xfe, 0x80, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], + unicast_link_local + ); + + check!( + "fec0::", + &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + unicast_site_local | unicast_global | global + ); + + check!( + "ff01::", + &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + multicast_interface_local + ); + + check!("ff02::", &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_link_local); + + check!("ff03::", &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_realm_local); + + check!("ff04::", &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_admin_local); + + check!("ff05::", &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], multicast_site_local); + + check!( + "ff08::", + &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + multicast_organization_local + ); + + check!( + "ff0e::", + &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + multicast_global | global + ); + + check!( + "2001:db8:85a3::8a2e:370:7334", + &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34], + documentation + ); + + check!( + "102:304:506:708:90a:b0c:d0e:f10", + &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + global | unicast_global + ); +} + +#[test] +fn to_socket_addr_socketaddr() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345); + assert_eq!(Ok(vec![a]), tsa(a)); +} + +#[test] +fn test_ipv4_to_int() { + let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44); + assert_eq!(u32::from(a), 0x11223344); +} + +#[test] +fn test_int_to_ipv4() { + let a = Ipv4Addr::new(0x11, 0x22, 0x33, 0x44); + assert_eq!(Ipv4Addr::from(0x11223344), a); +} + +#[test] +fn test_ipv6_to_int() { + let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11); + assert_eq!(u128::from(a), 0x112233445566778899aabbccddeeff11u128); +} + +#[test] +fn test_int_to_ipv6() { + let a = Ipv6Addr::new(0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff11); + assert_eq!(Ipv6Addr::from(0x112233445566778899aabbccddeeff11u128), a); +} + +#[test] +fn ipv4_from_constructors() { + assert_eq!(Ipv4Addr::LOCALHOST, Ipv4Addr::new(127, 0, 0, 1)); + assert!(Ipv4Addr::LOCALHOST.is_loopback()); + assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0)); + assert!(Ipv4Addr::UNSPECIFIED.is_unspecified()); + assert_eq!(Ipv4Addr::BROADCAST, Ipv4Addr::new(255, 255, 255, 255)); + assert!(Ipv4Addr::BROADCAST.is_broadcast()); +} + +#[test] +fn ipv6_from_contructors() { + assert_eq!(Ipv6Addr::LOCALHOST, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + assert!(Ipv6Addr::LOCALHOST.is_loopback()); + assert_eq!(Ipv6Addr::UNSPECIFIED, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + assert!(Ipv6Addr::UNSPECIFIED.is_unspecified()); +} + +#[test] +fn ipv4_from_octets() { + assert_eq!(Ipv4Addr::from([127, 0, 0, 1]), Ipv4Addr::new(127, 0, 0, 1)) +} + +#[test] +fn ipv6_from_segments() { + let from_u16s = + Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]); + let new = Ipv6Addr::new(0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff); + assert_eq!(new, from_u16s); +} + +#[test] +fn ipv6_from_octets() { + let from_u16s = + Ipv6Addr::from([0x0011, 0x2233, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff]); + let from_u8s = Ipv6Addr::from([ + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, + 0xff, + ]); + assert_eq!(from_u16s, from_u8s); +} + +#[test] +fn cmp() { + let v41 = Ipv4Addr::new(100, 64, 3, 3); + let v42 = Ipv4Addr::new(192, 0, 2, 2); + let v61 = "2001:db8:f00::1002".parse::<Ipv6Addr>().unwrap(); + let v62 = "2001:db8:f00::2001".parse::<Ipv6Addr>().unwrap(); + assert!(v41 < v42); + assert!(v61 < v62); + + assert_eq!(v41, IpAddr::V4(v41)); + assert_eq!(v61, IpAddr::V6(v61)); + assert!(v41 != IpAddr::V4(v42)); + assert!(v61 != IpAddr::V6(v62)); + + assert!(v41 < IpAddr::V4(v42)); + assert!(v61 < IpAddr::V6(v62)); + assert!(IpAddr::V4(v41) < v42); + assert!(IpAddr::V6(v61) < v62); + + assert!(v41 < IpAddr::V6(v61)); + assert!(IpAddr::V4(v41) < v61); +} + +#[test] +fn is_v4() { + let ip = IpAddr::V4(Ipv4Addr::new(100, 64, 3, 3)); + assert!(ip.is_ipv4()); + assert!(!ip.is_ipv6()); +} + +#[test] +fn is_v6() { + let ip = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x1234, 0x5678)); + assert!(!ip.is_ipv4()); + assert!(ip.is_ipv6()); +} diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index a425aca5a64..0570a7c41bf 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -3,6 +3,9 @@ //! This module is "publicly exported" through the `FromStr` implementations //! below. +#[cfg(test)] +mod tests; + use crate::error::Error; use crate::fmt; use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; @@ -321,146 +324,3 @@ impl Error for AddrParseError { "invalid IP address syntax" } } - -#[cfg(test)] -mod tests { - // FIXME: These tests are all excellent candidates for AFL fuzz testing - use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; - use crate::str::FromStr; - - const PORT: u16 = 8080; - - const IPV4: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1); - const IPV4_STR: &str = "192.168.0.1"; - const IPV4_STR_PORT: &str = "192.168.0.1:8080"; - - const IPV6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0xc0a8, 0x1); - const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1"; - const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1"; - const IPV6_STR_V4: &str = "2001:db8::192.168.0.1"; - const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080"; - - #[test] - fn parse_ipv4() { - let result: Ipv4Addr = IPV4_STR.parse().unwrap(); - assert_eq!(result, IPV4); - - assert!(Ipv4Addr::from_str(IPV4_STR_PORT).is_err()); - assert!(Ipv4Addr::from_str(IPV6_STR_FULL).is_err()); - assert!(Ipv4Addr::from_str(IPV6_STR_COMPRESS).is_err()); - assert!(Ipv4Addr::from_str(IPV6_STR_V4).is_err()); - assert!(Ipv4Addr::from_str(IPV6_STR_PORT).is_err()); - } - - #[test] - fn parse_ipv6() { - let result: Ipv6Addr = IPV6_STR_FULL.parse().unwrap(); - assert_eq!(result, IPV6); - - let result: Ipv6Addr = IPV6_STR_COMPRESS.parse().unwrap(); - assert_eq!(result, IPV6); - - let result: Ipv6Addr = IPV6_STR_V4.parse().unwrap(); - assert_eq!(result, IPV6); - - assert!(Ipv6Addr::from_str(IPV4_STR).is_err()); - assert!(Ipv6Addr::from_str(IPV4_STR_PORT).is_err()); - assert!(Ipv6Addr::from_str(IPV6_STR_PORT).is_err()); - } - - #[test] - fn parse_ip() { - let result: IpAddr = IPV4_STR.parse().unwrap(); - assert_eq!(result, IpAddr::from(IPV4)); - - let result: IpAddr = IPV6_STR_FULL.parse().unwrap(); - assert_eq!(result, IpAddr::from(IPV6)); - - let result: IpAddr = IPV6_STR_COMPRESS.parse().unwrap(); - assert_eq!(result, IpAddr::from(IPV6)); - - let result: IpAddr = IPV6_STR_V4.parse().unwrap(); - assert_eq!(result, IpAddr::from(IPV6)); - - assert!(IpAddr::from_str(IPV4_STR_PORT).is_err()); - assert!(IpAddr::from_str(IPV6_STR_PORT).is_err()); - } - - #[test] - fn parse_socket_v4() { - let result: SocketAddrV4 = IPV4_STR_PORT.parse().unwrap(); - assert_eq!(result, SocketAddrV4::new(IPV4, PORT)); - - assert!(SocketAddrV4::from_str(IPV4_STR).is_err()); - assert!(SocketAddrV4::from_str(IPV6_STR_FULL).is_err()); - assert!(SocketAddrV4::from_str(IPV6_STR_COMPRESS).is_err()); - assert!(SocketAddrV4::from_str(IPV6_STR_V4).is_err()); - assert!(SocketAddrV4::from_str(IPV6_STR_PORT).is_err()); - } - - #[test] - fn parse_socket_v6() { - let result: SocketAddrV6 = IPV6_STR_PORT.parse().unwrap(); - assert_eq!(result, SocketAddrV6::new(IPV6, PORT, 0, 0)); - - assert!(SocketAddrV6::from_str(IPV4_STR).is_err()); - assert!(SocketAddrV6::from_str(IPV4_STR_PORT).is_err()); - assert!(SocketAddrV6::from_str(IPV6_STR_FULL).is_err()); - assert!(SocketAddrV6::from_str(IPV6_STR_COMPRESS).is_err()); - assert!(SocketAddrV6::from_str(IPV6_STR_V4).is_err()); - } - - #[test] - fn parse_socket() { - let result: SocketAddr = IPV4_STR_PORT.parse().unwrap(); - assert_eq!(result, SocketAddr::from((IPV4, PORT))); - - let result: SocketAddr = IPV6_STR_PORT.parse().unwrap(); - assert_eq!(result, SocketAddr::from((IPV6, PORT))); - - assert!(SocketAddr::from_str(IPV4_STR).is_err()); - assert!(SocketAddr::from_str(IPV6_STR_FULL).is_err()); - assert!(SocketAddr::from_str(IPV6_STR_COMPRESS).is_err()); - assert!(SocketAddr::from_str(IPV6_STR_V4).is_err()); - } - - #[test] - fn ipv6_corner_cases() { - let result: Ipv6Addr = "1::".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0)); - - let result: Ipv6Addr = "1:1::".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(1, 1, 0, 0, 0, 0, 0, 0)); - - let result: Ipv6Addr = "::1".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); - - let result: Ipv6Addr = "::1:1".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 1, 1)); - - let result: Ipv6Addr = "::".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); - - let result: Ipv6Addr = "::192.168.0.1".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc0a8, 0x1)); - - let result: Ipv6Addr = "::1:192.168.0.1".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 1, 0xc0a8, 0x1)); - - let result: Ipv6Addr = "1:1:1:1:1:1:192.168.0.1".parse().unwrap(); - assert_eq!(result, Ipv6Addr::new(1, 1, 1, 1, 1, 1, 0xc0a8, 0x1)); - } - - // Things that might not seem like failures but are - #[test] - fn ipv6_corner_failures() { - // No IP address before the :: - assert!(Ipv6Addr::from_str("1:192.168.0.1::").is_err()); - - // :: must have at least 1 set of zeroes - assert!(Ipv6Addr::from_str("1:1:1:1::1:1:1:1").is_err()); - - // Need brackets for a port - assert!(SocketAddrV6::from_str("1:1:1:1:1:1:1:1:8080").is_err()); - } -} diff --git a/library/std/src/net/parser/tests.rs b/library/std/src/net/parser/tests.rs new file mode 100644 index 00000000000..ecf5a782c0c --- /dev/null +++ b/library/std/src/net/parser/tests.rs @@ -0,0 +1,139 @@ +// FIXME: These tests are all excellent candidates for AFL fuzz testing +use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; +use crate::str::FromStr; + +const PORT: u16 = 8080; + +const IPV4: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1); +const IPV4_STR: &str = "192.168.0.1"; +const IPV4_STR_PORT: &str = "192.168.0.1:8080"; + +const IPV6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0xc0a8, 0x1); +const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1"; +const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1"; +const IPV6_STR_V4: &str = "2001:db8::192.168.0.1"; +const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080"; + +#[test] +fn parse_ipv4() { + let result: Ipv4Addr = IPV4_STR.parse().unwrap(); + assert_eq!(result, IPV4); + + assert!(Ipv4Addr::from_str(IPV4_STR_PORT).is_err()); + assert!(Ipv4Addr::from_str(IPV6_STR_FULL).is_err()); + assert!(Ipv4Addr::from_str(IPV6_STR_COMPRESS).is_err()); + assert!(Ipv4Addr::from_str(IPV6_STR_V4).is_err()); + assert!(Ipv4Addr::from_str(IPV6_STR_PORT).is_err()); +} + +#[test] +fn parse_ipv6() { + let result: Ipv6Addr = IPV6_STR_FULL.parse().unwrap(); + assert_eq!(result, IPV6); + + let result: Ipv6Addr = IPV6_STR_COMPRESS.parse().unwrap(); + assert_eq!(result, IPV6); + + let result: Ipv6Addr = IPV6_STR_V4.parse().unwrap(); + assert_eq!(result, IPV6); + + assert!(Ipv6Addr::from_str(IPV4_STR).is_err()); + assert!(Ipv6Addr::from_str(IPV4_STR_PORT).is_err()); + assert!(Ipv6Addr::from_str(IPV6_STR_PORT).is_err()); +} + +#[test] +fn parse_ip() { + let result: IpAddr = IPV4_STR.parse().unwrap(); + assert_eq!(result, IpAddr::from(IPV4)); + + let result: IpAddr = IPV6_STR_FULL.parse().unwrap(); + assert_eq!(result, IpAddr::from(IPV6)); + + let result: IpAddr = IPV6_STR_COMPRESS.parse().unwrap(); + assert_eq!(result, IpAddr::from(IPV6)); + + let result: IpAddr = IPV6_STR_V4.parse().unwrap(); + assert_eq!(result, IpAddr::from(IPV6)); + + assert!(IpAddr::from_str(IPV4_STR_PORT).is_err()); + assert!(IpAddr::from_str(IPV6_STR_PORT).is_err()); +} + +#[test] +fn parse_socket_v4() { + let result: SocketAddrV4 = IPV4_STR_PORT.parse().unwrap(); + assert_eq!(result, SocketAddrV4::new(IPV4, PORT)); + + assert!(SocketAddrV4::from_str(IPV4_STR).is_err()); + assert!(SocketAddrV4::from_str(IPV6_STR_FULL).is_err()); + assert!(SocketAddrV4::from_str(IPV6_STR_COMPRESS).is_err()); + assert!(SocketAddrV4::from_str(IPV6_STR_V4).is_err()); + assert!(SocketAddrV4::from_str(IPV6_STR_PORT).is_err()); +} + +#[test] +fn parse_socket_v6() { + let result: SocketAddrV6 = IPV6_STR_PORT.parse().unwrap(); + assert_eq!(result, SocketAddrV6::new(IPV6, PORT, 0, 0)); + + assert!(SocketAddrV6::from_str(IPV4_STR).is_err()); + assert!(SocketAddrV6::from_str(IPV4_STR_PORT).is_err()); + assert!(SocketAddrV6::from_str(IPV6_STR_FULL).is_err()); + assert!(SocketAddrV6::from_str(IPV6_STR_COMPRESS).is_err()); + assert!(SocketAddrV6::from_str(IPV6_STR_V4).is_err()); +} + +#[test] +fn parse_socket() { + let result: SocketAddr = IPV4_STR_PORT.parse().unwrap(); + assert_eq!(result, SocketAddr::from((IPV4, PORT))); + + let result: SocketAddr = IPV6_STR_PORT.parse().unwrap(); + assert_eq!(result, SocketAddr::from((IPV6, PORT))); + + assert!(SocketAddr::from_str(IPV4_STR).is_err()); + assert!(SocketAddr::from_str(IPV6_STR_FULL).is_err()); + assert!(SocketAddr::from_str(IPV6_STR_COMPRESS).is_err()); + assert!(SocketAddr::from_str(IPV6_STR_V4).is_err()); +} + +#[test] +fn ipv6_corner_cases() { + let result: Ipv6Addr = "1::".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0)); + + let result: Ipv6Addr = "1:1::".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(1, 1, 0, 0, 0, 0, 0, 0)); + + let result: Ipv6Addr = "::1".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + + let result: Ipv6Addr = "::1:1".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 1, 1)); + + let result: Ipv6Addr = "::".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + + let result: Ipv6Addr = "::192.168.0.1".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc0a8, 0x1)); + + let result: Ipv6Addr = "::1:192.168.0.1".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(0, 0, 0, 0, 0, 1, 0xc0a8, 0x1)); + + let result: Ipv6Addr = "1:1:1:1:1:1:192.168.0.1".parse().unwrap(); + assert_eq!(result, Ipv6Addr::new(1, 1, 1, 1, 1, 1, 0xc0a8, 0x1)); +} + +// Things that might not seem like failures but are +#[test] +fn ipv6_corner_failures() { + // No IP address before the :: + assert!(Ipv6Addr::from_str("1:192.168.0.1::").is_err()); + + // :: must have at least 1 set of zeroes + assert!(Ipv6Addr::from_str("1:1:1:1::1:1:1:1").is_err()); + + // Need brackets for a port + assert!(SocketAddrV6::from_str("1:1:1:1:1:1:1:1:8080").is_err()); +} diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index a76c9c46c05..58c6343ea34 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -1,4 +1,8 @@ #![deny(unsafe_op_in_unsafe_fn)] + +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] +mod tests; + use crate::io::prelude::*; use crate::fmt; @@ -936,869 +940,3 @@ impl fmt::Debug for TcpListener { self.0.fmt(f) } } - -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] -mod tests { - use crate::fmt; - use crate::io::prelude::*; - use crate::io::{ErrorKind, IoSlice, IoSliceMut}; - use crate::net::test::{next_test_ip4, next_test_ip6}; - use crate::net::*; - use crate::sync::mpsc::channel; - use crate::thread; - use crate::time::{Duration, Instant}; - - fn each_ip(f: &mut dyn FnMut(SocketAddr)) { - f(next_test_ip4()); - f(next_test_ip6()); - } - - macro_rules! t { - ($e:expr) => { - match $e { - Ok(t) => t, - Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), - } - }; - } - - #[test] - fn bind_error() { - match TcpListener::bind("1.1.1.1:9999") { - Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable), - } - } - - #[test] - fn connect_error() { - match TcpStream::connect("0.0.0.0:1") { - Ok(..) => panic!(), - Err(e) => assert!( - e.kind() == ErrorKind::ConnectionRefused - || e.kind() == ErrorKind::InvalidInput - || e.kind() == ErrorKind::AddrInUse - || e.kind() == ErrorKind::AddrNotAvailable, - "bad error: {} {:?}", - e, - e.kind() - ), - } - } - - #[test] - fn listen_localhost() { - let socket_addr = next_test_ip4(); - let listener = t!(TcpListener::bind(&socket_addr)); - - let _t = thread::spawn(move || { - let mut stream = t!(TcpStream::connect(&("localhost", socket_addr.port()))); - t!(stream.write(&[144])); - }); - - let mut stream = t!(listener.accept()).0; - let mut buf = [0]; - t!(stream.read(&mut buf)); - assert!(buf[0] == 144); - } - - #[test] - fn connect_loopback() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - let host = match addr { - SocketAddr::V4(..) => "127.0.0.1", - SocketAddr::V6(..) => "::1", - }; - let mut stream = t!(TcpStream::connect(&(host, addr.port()))); - t!(stream.write(&[66])); - }); - - let mut stream = t!(acceptor.accept()).0; - let mut buf = [0]; - t!(stream.read(&mut buf)); - assert!(buf[0] == 66); - }) - } - - #[test] - fn smoke_test() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - let mut stream = t!(TcpStream::connect(&addr)); - t!(stream.write(&[99])); - tx.send(t!(stream.local_addr())).unwrap(); - }); - - let (mut stream, addr) = t!(acceptor.accept()); - let mut buf = [0]; - t!(stream.read(&mut buf)); - assert!(buf[0] == 99); - assert_eq!(addr, t!(rx.recv())); - }) - } - - #[test] - fn read_eof() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - let _stream = t!(TcpStream::connect(&addr)); - // Close - }); - - let mut stream = t!(acceptor.accept()).0; - let mut buf = [0]; - let nread = t!(stream.read(&mut buf)); - assert_eq!(nread, 0); - let nread = t!(stream.read(&mut buf)); - assert_eq!(nread, 0); - }) - } - - #[test] - fn write_close() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - drop(t!(TcpStream::connect(&addr))); - tx.send(()).unwrap(); - }); - - let mut stream = t!(acceptor.accept()).0; - rx.recv().unwrap(); - let buf = [0]; - match stream.write(&buf) { - Ok(..) => {} - Err(e) => { - assert!( - e.kind() == ErrorKind::ConnectionReset - || e.kind() == ErrorKind::BrokenPipe - || e.kind() == ErrorKind::ConnectionAborted, - "unknown error: {}", - e - ); - } - } - }) - } - - #[test] - fn multiple_connect_serial() { - each_ip(&mut |addr| { - let max = 10; - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - for _ in 0..max { - let mut stream = t!(TcpStream::connect(&addr)); - t!(stream.write(&[99])); - } - }); - - for stream in acceptor.incoming().take(max) { - let mut stream = t!(stream); - let mut buf = [0]; - t!(stream.read(&mut buf)); - assert_eq!(buf[0], 99); - } - }) - } - - #[test] - fn multiple_connect_interleaved_greedy_schedule() { - const MAX: usize = 10; - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - let acceptor = acceptor; - for (i, stream) in acceptor.incoming().enumerate().take(MAX) { - // Start another thread to handle the connection - let _t = thread::spawn(move || { - let mut stream = t!(stream); - let mut buf = [0]; - t!(stream.read(&mut buf)); - assert!(buf[0] == i as u8); - }); - } - }); - - connect(0, addr); - }); - - fn connect(i: usize, addr: SocketAddr) { - if i == MAX { - return; - } - - let t = thread::spawn(move || { - let mut stream = t!(TcpStream::connect(&addr)); - // Connect again before writing - connect(i + 1, addr); - t!(stream.write(&[i as u8])); - }); - t.join().ok().expect("thread panicked"); - } - } - - #[test] - fn multiple_connect_interleaved_lazy_schedule() { - const MAX: usize = 10; - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - for stream in acceptor.incoming().take(MAX) { - // Start another thread to handle the connection - let _t = thread::spawn(move || { - let mut stream = t!(stream); - let mut buf = [0]; - t!(stream.read(&mut buf)); - assert!(buf[0] == 99); - }); - } - }); - - connect(0, addr); - }); - - fn connect(i: usize, addr: SocketAddr) { - if i == MAX { - return; - } - - let t = thread::spawn(move || { - let mut stream = t!(TcpStream::connect(&addr)); - connect(i + 1, addr); - t!(stream.write(&[99])); - }); - t.join().ok().expect("thread panicked"); - } - } - - #[test] - fn socket_and_peer_name() { - each_ip(&mut |addr| { - let listener = t!(TcpListener::bind(&addr)); - let so_name = t!(listener.local_addr()); - assert_eq!(addr, so_name); - let _t = thread::spawn(move || { - t!(listener.accept()); - }); - - let stream = t!(TcpStream::connect(&addr)); - assert_eq!(addr, t!(stream.peer_addr())); - }) - } - - #[test] - fn partial_read() { - each_ip(&mut |addr| { - let (tx, rx) = channel(); - let srv = t!(TcpListener::bind(&addr)); - let _t = thread::spawn(move || { - let mut cl = t!(srv.accept()).0; - cl.write(&[10]).unwrap(); - let mut b = [0]; - t!(cl.read(&mut b)); - tx.send(()).unwrap(); - }); - - let mut c = t!(TcpStream::connect(&addr)); - let mut b = [0; 10]; - assert_eq!(c.read(&mut b).unwrap(), 1); - t!(c.write(&[1])); - rx.recv().unwrap(); - }) - } - - #[test] - fn read_vectored() { - each_ip(&mut |addr| { - let srv = t!(TcpListener::bind(&addr)); - let mut s1 = t!(TcpStream::connect(&addr)); - let mut s2 = t!(srv.accept()).0; - - let len = s1.write(&[10, 11, 12]).unwrap(); - assert_eq!(len, 3); - - let mut a = []; - let mut b = [0]; - let mut c = [0; 3]; - let len = t!(s2.read_vectored(&mut [ - IoSliceMut::new(&mut a), - IoSliceMut::new(&mut b), - IoSliceMut::new(&mut c) - ],)); - assert!(len > 0); - assert_eq!(b, [10]); - // some implementations don't support readv, so we may only fill the first buffer - assert!(len == 1 || c == [11, 12, 0]); - }) - } - - #[test] - fn write_vectored() { - each_ip(&mut |addr| { - let srv = t!(TcpListener::bind(&addr)); - let mut s1 = t!(TcpStream::connect(&addr)); - let mut s2 = t!(srv.accept()).0; - - let a = []; - let b = [10]; - let c = [11, 12]; - t!(s1.write_vectored(&[IoSlice::new(&a), IoSlice::new(&b), IoSlice::new(&c)])); - - let mut buf = [0; 4]; - let len = t!(s2.read(&mut buf)); - // some implementations don't support writev, so we may only write the first buffer - if len == 1 { - assert_eq!(buf, [10, 0, 0, 0]); - } else { - assert_eq!(len, 3); - assert_eq!(buf, [10, 11, 12, 0]); - } - }) - } - - #[test] - fn double_bind() { - each_ip(&mut |addr| { - let listener1 = t!(TcpListener::bind(&addr)); - match TcpListener::bind(&addr) { - Ok(listener2) => panic!( - "This system (perhaps due to options set by TcpListener::bind) \ - permits double binding: {:?} and {:?}", - listener1, listener2 - ), - Err(e) => { - assert!( - e.kind() == ErrorKind::ConnectionRefused - || e.kind() == ErrorKind::Other - || e.kind() == ErrorKind::AddrInUse, - "unknown error: {} {:?}", - e, - e.kind() - ); - } - } - }) - } - - #[test] - fn tcp_clone_smoke() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - let mut s = t!(TcpStream::connect(&addr)); - let mut buf = [0, 0]; - assert_eq!(s.read(&mut buf).unwrap(), 1); - assert_eq!(buf[0], 1); - t!(s.write(&[2])); - }); - - let mut s1 = t!(acceptor.accept()).0; - let s2 = t!(s1.try_clone()); - - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - let _t = thread::spawn(move || { - let mut s2 = s2; - rx1.recv().unwrap(); - t!(s2.write(&[1])); - tx2.send(()).unwrap(); - }); - tx1.send(()).unwrap(); - let mut buf = [0, 0]; - assert_eq!(s1.read(&mut buf).unwrap(), 1); - rx2.recv().unwrap(); - }) - } - - #[test] - fn tcp_clone_two_read() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - let (tx1, rx) = channel(); - let tx2 = tx1.clone(); - - let _t = thread::spawn(move || { - let mut s = t!(TcpStream::connect(&addr)); - t!(s.write(&[1])); - rx.recv().unwrap(); - t!(s.write(&[2])); - rx.recv().unwrap(); - }); - - let mut s1 = t!(acceptor.accept()).0; - let s2 = t!(s1.try_clone()); - - let (done, rx) = channel(); - let _t = thread::spawn(move || { - let mut s2 = s2; - let mut buf = [0, 0]; - t!(s2.read(&mut buf)); - tx2.send(()).unwrap(); - done.send(()).unwrap(); - }); - let mut buf = [0, 0]; - t!(s1.read(&mut buf)); - tx1.send(()).unwrap(); - - rx.recv().unwrap(); - }) - } - - #[test] - fn tcp_clone_two_write() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - let mut s = t!(TcpStream::connect(&addr)); - let mut buf = [0, 1]; - t!(s.read(&mut buf)); - t!(s.read(&mut buf)); - }); - - let mut s1 = t!(acceptor.accept()).0; - let s2 = t!(s1.try_clone()); - - let (done, rx) = channel(); - let _t = thread::spawn(move || { - let mut s2 = s2; - t!(s2.write(&[1])); - done.send(()).unwrap(); - }); - t!(s1.write(&[2])); - - rx.recv().unwrap(); - }) - } - - #[test] - // FIXME: https://github.com/fortanix/rust-sgx/issues/110 - #[cfg_attr(target_env = "sgx", ignore)] - fn shutdown_smoke() { - each_ip(&mut |addr| { - let a = t!(TcpListener::bind(&addr)); - let _t = thread::spawn(move || { - let mut c = t!(a.accept()).0; - let mut b = [0]; - assert_eq!(c.read(&mut b).unwrap(), 0); - t!(c.write(&[1])); - }); - - let mut s = t!(TcpStream::connect(&addr)); - t!(s.shutdown(Shutdown::Write)); - assert!(s.write(&[1]).is_err()); - let mut b = [0, 0]; - assert_eq!(t!(s.read(&mut b)), 1); - assert_eq!(b[0], 1); - }) - } - - #[test] - // FIXME: https://github.com/fortanix/rust-sgx/issues/110 - #[cfg_attr(target_env = "sgx", ignore)] - fn close_readwrite_smoke() { - each_ip(&mut |addr| { - let a = t!(TcpListener::bind(&addr)); - let (tx, rx) = channel::<()>(); - let _t = thread::spawn(move || { - let _s = t!(a.accept()); - let _ = rx.recv(); - }); - - let mut b = [0]; - let mut s = t!(TcpStream::connect(&addr)); - let mut s2 = t!(s.try_clone()); - - // closing should prevent reads/writes - t!(s.shutdown(Shutdown::Write)); - assert!(s.write(&[0]).is_err()); - t!(s.shutdown(Shutdown::Read)); - assert_eq!(s.read(&mut b).unwrap(), 0); - - // closing should affect previous handles - assert!(s2.write(&[0]).is_err()); - assert_eq!(s2.read(&mut b).unwrap(), 0); - - // closing should affect new handles - let mut s3 = t!(s.try_clone()); - assert!(s3.write(&[0]).is_err()); - assert_eq!(s3.read(&mut b).unwrap(), 0); - - // make sure these don't die - let _ = s2.shutdown(Shutdown::Read); - let _ = s2.shutdown(Shutdown::Write); - let _ = s3.shutdown(Shutdown::Read); - let _ = s3.shutdown(Shutdown::Write); - drop(tx); - }) - } - - #[test] - #[cfg(unix)] // test doesn't work on Windows, see #31657 - fn close_read_wakes_up() { - each_ip(&mut |addr| { - let a = t!(TcpListener::bind(&addr)); - let (tx1, rx) = channel::<()>(); - let _t = thread::spawn(move || { - let _s = t!(a.accept()); - let _ = rx.recv(); - }); - - let s = t!(TcpStream::connect(&addr)); - let s2 = t!(s.try_clone()); - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - let mut s2 = s2; - assert_eq!(t!(s2.read(&mut [0])), 0); - tx.send(()).unwrap(); - }); - // this should wake up the child thread - t!(s.shutdown(Shutdown::Read)); - - // this test will never finish if the child doesn't wake up - rx.recv().unwrap(); - drop(tx1); - }) - } - - #[test] - fn clone_while_reading() { - each_ip(&mut |addr| { - let accept = t!(TcpListener::bind(&addr)); - - // Enqueue a thread to write to a socket - let (tx, rx) = channel(); - let (txdone, rxdone) = channel(); - let txdone2 = txdone.clone(); - let _t = thread::spawn(move || { - let mut tcp = t!(TcpStream::connect(&addr)); - rx.recv().unwrap(); - t!(tcp.write(&[0])); - txdone2.send(()).unwrap(); - }); - - // Spawn off a reading clone - let tcp = t!(accept.accept()).0; - let tcp2 = t!(tcp.try_clone()); - let txdone3 = txdone.clone(); - let _t = thread::spawn(move || { - let mut tcp2 = tcp2; - t!(tcp2.read(&mut [0])); - txdone3.send(()).unwrap(); - }); - - // Try to ensure that the reading clone is indeed reading - for _ in 0..50 { - thread::yield_now(); - } - - // clone the handle again while it's reading, then let it finish the - // read. - let _ = t!(tcp.try_clone()); - tx.send(()).unwrap(); - rxdone.recv().unwrap(); - rxdone.recv().unwrap(); - }) - } - - #[test] - fn clone_accept_smoke() { - each_ip(&mut |addr| { - let a = t!(TcpListener::bind(&addr)); - let a2 = t!(a.try_clone()); - - let _t = thread::spawn(move || { - let _ = TcpStream::connect(&addr); - }); - let _t = thread::spawn(move || { - let _ = TcpStream::connect(&addr); - }); - - t!(a.accept()); - t!(a2.accept()); - }) - } - - #[test] - fn clone_accept_concurrent() { - each_ip(&mut |addr| { - let a = t!(TcpListener::bind(&addr)); - let a2 = t!(a.try_clone()); - - let (tx, rx) = channel(); - let tx2 = tx.clone(); - - let _t = thread::spawn(move || { - tx.send(t!(a.accept())).unwrap(); - }); - let _t = thread::spawn(move || { - tx2.send(t!(a2.accept())).unwrap(); - }); - - let _t = thread::spawn(move || { - let _ = TcpStream::connect(&addr); - }); - let _t = thread::spawn(move || { - let _ = TcpStream::connect(&addr); - }); - - rx.recv().unwrap(); - rx.recv().unwrap(); - }) - } - - #[test] - fn debug() { - #[cfg(not(target_env = "sgx"))] - fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a { - addr - } - #[cfg(target_env = "sgx")] - fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a { - addr.to_string() - } - - #[cfg(target_env = "sgx")] - use crate::os::fortanix_sgx::io::AsRawFd; - #[cfg(unix)] - use crate::os::unix::io::AsRawFd; - #[cfg(not(windows))] - fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug { - addr.as_raw_fd() - } - #[cfg(windows)] - fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Debug { - addr.as_raw_socket() - } - - let inner_name = if cfg!(windows) { "socket" } else { "fd" }; - let socket_addr = next_test_ip4(); - - let listener = t!(TcpListener::bind(&socket_addr)); - let compare = format!( - "TcpListener {{ addr: {:?}, {}: {:?} }}", - render_socket_addr(&socket_addr), - inner_name, - render_inner(&listener) - ); - assert_eq!(format!("{:?}", listener), compare); - - let stream = t!(TcpStream::connect(&("localhost", socket_addr.port()))); - let compare = format!( - "TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}", - render_socket_addr(&stream.local_addr().unwrap()), - render_socket_addr(&stream.peer_addr().unwrap()), - inner_name, - render_inner(&stream) - ); - assert_eq!(format!("{:?}", stream), compare); - } - - // FIXME: re-enabled openbsd tests once their socket timeout code - // no longer has rounding errors. - // VxWorks ignores SO_SNDTIMEO. - #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - #[test] - fn timeouts() { - let addr = next_test_ip4(); - let listener = t!(TcpListener::bind(&addr)); - - let stream = t!(TcpStream::connect(&("localhost", addr.port()))); - let dur = Duration::new(15410, 0); - - assert_eq!(None, t!(stream.read_timeout())); - - t!(stream.set_read_timeout(Some(dur))); - assert_eq!(Some(dur), t!(stream.read_timeout())); - - assert_eq!(None, t!(stream.write_timeout())); - - t!(stream.set_write_timeout(Some(dur))); - assert_eq!(Some(dur), t!(stream.write_timeout())); - - t!(stream.set_read_timeout(None)); - assert_eq!(None, t!(stream.read_timeout())); - - t!(stream.set_write_timeout(None)); - assert_eq!(None, t!(stream.write_timeout())); - drop(listener); - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - fn test_read_timeout() { - let addr = next_test_ip4(); - let listener = t!(TcpListener::bind(&addr)); - - let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); - - let mut buf = [0; 10]; - let start = Instant::now(); - let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); - assert!( - kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, - "unexpected_error: {:?}", - kind - ); - assert!(start.elapsed() > Duration::from_millis(400)); - drop(listener); - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - fn test_read_with_timeout() { - let addr = next_test_ip4(); - let listener = t!(TcpListener::bind(&addr)); - - let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); - - let mut other_end = t!(listener.accept()).0; - t!(other_end.write_all(b"hello world")); - - let mut buf = [0; 11]; - t!(stream.read(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - - let start = Instant::now(); - let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); - assert!( - kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, - "unexpected_error: {:?}", - kind - ); - assert!(start.elapsed() > Duration::from_millis(400)); - drop(listener); - } - - // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors - // when passed zero Durations - #[test] - fn test_timeout_zero_duration() { - let addr = next_test_ip4(); - - let listener = t!(TcpListener::bind(&addr)); - let stream = t!(TcpStream::connect(&addr)); - - let result = stream.set_write_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - - let result = stream.set_read_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - - drop(listener); - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] - fn nodelay() { - let addr = next_test_ip4(); - let _listener = t!(TcpListener::bind(&addr)); - - let stream = t!(TcpStream::connect(&("localhost", addr.port()))); - - assert_eq!(false, t!(stream.nodelay())); - t!(stream.set_nodelay(true)); - assert_eq!(true, t!(stream.nodelay())); - t!(stream.set_nodelay(false)); - assert_eq!(false, t!(stream.nodelay())); - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] - fn ttl() { - let ttl = 100; - - let addr = next_test_ip4(); - let listener = t!(TcpListener::bind(&addr)); - - t!(listener.set_ttl(ttl)); - assert_eq!(ttl, t!(listener.ttl())); - - let stream = t!(TcpStream::connect(&("localhost", addr.port()))); - - t!(stream.set_ttl(ttl)); - assert_eq!(ttl, t!(stream.ttl())); - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] - fn set_nonblocking() { - let addr = next_test_ip4(); - let listener = t!(TcpListener::bind(&addr)); - - t!(listener.set_nonblocking(true)); - t!(listener.set_nonblocking(false)); - - let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); - - t!(stream.set_nonblocking(false)); - t!(stream.set_nonblocking(true)); - - let mut buf = [0]; - match stream.read(&mut buf) { - Ok(_) => panic!("expected error"), - Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} - Err(e) => panic!("unexpected error {}", e), - } - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - fn peek() { - each_ip(&mut |addr| { - let (txdone, rxdone) = channel(); - - let srv = t!(TcpListener::bind(&addr)); - let _t = thread::spawn(move || { - let mut cl = t!(srv.accept()).0; - cl.write(&[1, 3, 3, 7]).unwrap(); - t!(rxdone.recv()); - }); - - let mut c = t!(TcpStream::connect(&addr)); - let mut b = [0; 10]; - for _ in 1..3 { - let len = c.peek(&mut b).unwrap(); - assert_eq!(len, 4); - } - let len = c.read(&mut b).unwrap(); - assert_eq!(len, 4); - - t!(c.set_nonblocking(true)); - match c.peek(&mut b) { - Ok(_) => panic!("expected error"), - Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} - Err(e) => panic!("unexpected error {}", e), - } - t!(txdone.send(())); - }) - } - - #[test] - #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 - fn connect_timeout_valid() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - TcpStream::connect_timeout(&addr, Duration::from_secs(2)).unwrap(); - } -} diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs new file mode 100644 index 00000000000..abe9bc24cec --- /dev/null +++ b/library/std/src/net/tcp/tests.rs @@ -0,0 +1,862 @@ +use crate::fmt; +use crate::io::prelude::*; +use crate::io::{ErrorKind, IoSlice, IoSliceMut}; +use crate::net::test::{next_test_ip4, next_test_ip6}; +use crate::net::*; +use crate::sync::mpsc::channel; +use crate::thread; +use crate::time::{Duration, Instant}; + +fn each_ip(f: &mut dyn FnMut(SocketAddr)) { + f(next_test_ip4()); + f(next_test_ip6()); +} + +macro_rules! t { + ($e:expr) => { + match $e { + Ok(t) => t, + Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), + } + }; +} + +#[test] +fn bind_error() { + match TcpListener::bind("1.1.1.1:9999") { + Ok(..) => panic!(), + Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable), + } +} + +#[test] +fn connect_error() { + match TcpStream::connect("0.0.0.0:1") { + Ok(..) => panic!(), + Err(e) => assert!( + e.kind() == ErrorKind::ConnectionRefused + || e.kind() == ErrorKind::InvalidInput + || e.kind() == ErrorKind::AddrInUse + || e.kind() == ErrorKind::AddrNotAvailable, + "bad error: {} {:?}", + e, + e.kind() + ), + } +} + +#[test] +fn listen_localhost() { + let socket_addr = next_test_ip4(); + let listener = t!(TcpListener::bind(&socket_addr)); + + let _t = thread::spawn(move || { + let mut stream = t!(TcpStream::connect(&("localhost", socket_addr.port()))); + t!(stream.write(&[144])); + }); + + let mut stream = t!(listener.accept()).0; + let mut buf = [0]; + t!(stream.read(&mut buf)); + assert!(buf[0] == 144); +} + +#[test] +fn connect_loopback() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + let host = match addr { + SocketAddr::V4(..) => "127.0.0.1", + SocketAddr::V6(..) => "::1", + }; + let mut stream = t!(TcpStream::connect(&(host, addr.port()))); + t!(stream.write(&[66])); + }); + + let mut stream = t!(acceptor.accept()).0; + let mut buf = [0]; + t!(stream.read(&mut buf)); + assert!(buf[0] == 66); + }) +} + +#[test] +fn smoke_test() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let (tx, rx) = channel(); + let _t = thread::spawn(move || { + let mut stream = t!(TcpStream::connect(&addr)); + t!(stream.write(&[99])); + tx.send(t!(stream.local_addr())).unwrap(); + }); + + let (mut stream, addr) = t!(acceptor.accept()); + let mut buf = [0]; + t!(stream.read(&mut buf)); + assert!(buf[0] == 99); + assert_eq!(addr, t!(rx.recv())); + }) +} + +#[test] +fn read_eof() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + let _stream = t!(TcpStream::connect(&addr)); + // Close + }); + + let mut stream = t!(acceptor.accept()).0; + let mut buf = [0]; + let nread = t!(stream.read(&mut buf)); + assert_eq!(nread, 0); + let nread = t!(stream.read(&mut buf)); + assert_eq!(nread, 0); + }) +} + +#[test] +fn write_close() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let (tx, rx) = channel(); + let _t = thread::spawn(move || { + drop(t!(TcpStream::connect(&addr))); + tx.send(()).unwrap(); + }); + + let mut stream = t!(acceptor.accept()).0; + rx.recv().unwrap(); + let buf = [0]; + match stream.write(&buf) { + Ok(..) => {} + Err(e) => { + assert!( + e.kind() == ErrorKind::ConnectionReset + || e.kind() == ErrorKind::BrokenPipe + || e.kind() == ErrorKind::ConnectionAborted, + "unknown error: {}", + e + ); + } + } + }) +} + +#[test] +fn multiple_connect_serial() { + each_ip(&mut |addr| { + let max = 10; + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + for _ in 0..max { + let mut stream = t!(TcpStream::connect(&addr)); + t!(stream.write(&[99])); + } + }); + + for stream in acceptor.incoming().take(max) { + let mut stream = t!(stream); + let mut buf = [0]; + t!(stream.read(&mut buf)); + assert_eq!(buf[0], 99); + } + }) +} + +#[test] +fn multiple_connect_interleaved_greedy_schedule() { + const MAX: usize = 10; + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + let acceptor = acceptor; + for (i, stream) in acceptor.incoming().enumerate().take(MAX) { + // Start another thread to handle the connection + let _t = thread::spawn(move || { + let mut stream = t!(stream); + let mut buf = [0]; + t!(stream.read(&mut buf)); + assert!(buf[0] == i as u8); + }); + } + }); + + connect(0, addr); + }); + + fn connect(i: usize, addr: SocketAddr) { + if i == MAX { + return; + } + + let t = thread::spawn(move || { + let mut stream = t!(TcpStream::connect(&addr)); + // Connect again before writing + connect(i + 1, addr); + t!(stream.write(&[i as u8])); + }); + t.join().ok().expect("thread panicked"); + } +} + +#[test] +fn multiple_connect_interleaved_lazy_schedule() { + const MAX: usize = 10; + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + for stream in acceptor.incoming().take(MAX) { + // Start another thread to handle the connection + let _t = thread::spawn(move || { + let mut stream = t!(stream); + let mut buf = [0]; + t!(stream.read(&mut buf)); + assert!(buf[0] == 99); + }); + } + }); + + connect(0, addr); + }); + + fn connect(i: usize, addr: SocketAddr) { + if i == MAX { + return; + } + + let t = thread::spawn(move || { + let mut stream = t!(TcpStream::connect(&addr)); + connect(i + 1, addr); + t!(stream.write(&[99])); + }); + t.join().ok().expect("thread panicked"); + } +} + +#[test] +fn socket_and_peer_name() { + each_ip(&mut |addr| { + let listener = t!(TcpListener::bind(&addr)); + let so_name = t!(listener.local_addr()); + assert_eq!(addr, so_name); + let _t = thread::spawn(move || { + t!(listener.accept()); + }); + + let stream = t!(TcpStream::connect(&addr)); + assert_eq!(addr, t!(stream.peer_addr())); + }) +} + +#[test] +fn partial_read() { + each_ip(&mut |addr| { + let (tx, rx) = channel(); + let srv = t!(TcpListener::bind(&addr)); + let _t = thread::spawn(move || { + let mut cl = t!(srv.accept()).0; + cl.write(&[10]).unwrap(); + let mut b = [0]; + t!(cl.read(&mut b)); + tx.send(()).unwrap(); + }); + + let mut c = t!(TcpStream::connect(&addr)); + let mut b = [0; 10]; + assert_eq!(c.read(&mut b).unwrap(), 1); + t!(c.write(&[1])); + rx.recv().unwrap(); + }) +} + +#[test] +fn read_vectored() { + each_ip(&mut |addr| { + let srv = t!(TcpListener::bind(&addr)); + let mut s1 = t!(TcpStream::connect(&addr)); + let mut s2 = t!(srv.accept()).0; + + let len = s1.write(&[10, 11, 12]).unwrap(); + assert_eq!(len, 3); + + let mut a = []; + let mut b = [0]; + let mut c = [0; 3]; + let len = t!(s2.read_vectored(&mut [ + IoSliceMut::new(&mut a), + IoSliceMut::new(&mut b), + IoSliceMut::new(&mut c) + ],)); + assert!(len > 0); + assert_eq!(b, [10]); + // some implementations don't support readv, so we may only fill the first buffer + assert!(len == 1 || c == [11, 12, 0]); + }) +} + +#[test] +fn write_vectored() { + each_ip(&mut |addr| { + let srv = t!(TcpListener::bind(&addr)); + let mut s1 = t!(TcpStream::connect(&addr)); + let mut s2 = t!(srv.accept()).0; + + let a = []; + let b = [10]; + let c = [11, 12]; + t!(s1.write_vectored(&[IoSlice::new(&a), IoSlice::new(&b), IoSlice::new(&c)])); + + let mut buf = [0; 4]; + let len = t!(s2.read(&mut buf)); + // some implementations don't support writev, so we may only write the first buffer + if len == 1 { + assert_eq!(buf, [10, 0, 0, 0]); + } else { + assert_eq!(len, 3); + assert_eq!(buf, [10, 11, 12, 0]); + } + }) +} + +#[test] +fn double_bind() { + each_ip(&mut |addr| { + let listener1 = t!(TcpListener::bind(&addr)); + match TcpListener::bind(&addr) { + Ok(listener2) => panic!( + "This system (perhaps due to options set by TcpListener::bind) \ + permits double binding: {:?} and {:?}", + listener1, listener2 + ), + Err(e) => { + assert!( + e.kind() == ErrorKind::ConnectionRefused + || e.kind() == ErrorKind::Other + || e.kind() == ErrorKind::AddrInUse, + "unknown error: {} {:?}", + e, + e.kind() + ); + } + } + }) +} + +#[test] +fn tcp_clone_smoke() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + let mut s = t!(TcpStream::connect(&addr)); + let mut buf = [0, 0]; + assert_eq!(s.read(&mut buf).unwrap(), 1); + assert_eq!(buf[0], 1); + t!(s.write(&[2])); + }); + + let mut s1 = t!(acceptor.accept()).0; + let s2 = t!(s1.try_clone()); + + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + let _t = thread::spawn(move || { + let mut s2 = s2; + rx1.recv().unwrap(); + t!(s2.write(&[1])); + tx2.send(()).unwrap(); + }); + tx1.send(()).unwrap(); + let mut buf = [0, 0]; + assert_eq!(s1.read(&mut buf).unwrap(), 1); + rx2.recv().unwrap(); + }) +} + +#[test] +fn tcp_clone_two_read() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + let (tx1, rx) = channel(); + let tx2 = tx1.clone(); + + let _t = thread::spawn(move || { + let mut s = t!(TcpStream::connect(&addr)); + t!(s.write(&[1])); + rx.recv().unwrap(); + t!(s.write(&[2])); + rx.recv().unwrap(); + }); + + let mut s1 = t!(acceptor.accept()).0; + let s2 = t!(s1.try_clone()); + + let (done, rx) = channel(); + let _t = thread::spawn(move || { + let mut s2 = s2; + let mut buf = [0, 0]; + t!(s2.read(&mut buf)); + tx2.send(()).unwrap(); + done.send(()).unwrap(); + }); + let mut buf = [0, 0]; + t!(s1.read(&mut buf)); + tx1.send(()).unwrap(); + + rx.recv().unwrap(); + }) +} + +#[test] +fn tcp_clone_two_write() { + each_ip(&mut |addr| { + let acceptor = t!(TcpListener::bind(&addr)); + + let _t = thread::spawn(move || { + let mut s = t!(TcpStream::connect(&addr)); + let mut buf = [0, 1]; + t!(s.read(&mut buf)); + t!(s.read(&mut buf)); + }); + + let mut s1 = t!(acceptor.accept()).0; + let s2 = t!(s1.try_clone()); + + let (done, rx) = channel(); + let _t = thread::spawn(move || { + let mut s2 = s2; + t!(s2.write(&[1])); + done.send(()).unwrap(); + }); + t!(s1.write(&[2])); + + rx.recv().unwrap(); + }) +} + +#[test] +// FIXME: https://github.com/fortanix/rust-sgx/issues/110 +#[cfg_attr(target_env = "sgx", ignore)] +fn shutdown_smoke() { + each_ip(&mut |addr| { + let a = t!(TcpListener::bind(&addr)); + let _t = thread::spawn(move || { + let mut c = t!(a.accept()).0; + let mut b = [0]; + assert_eq!(c.read(&mut b).unwrap(), 0); + t!(c.write(&[1])); + }); + + let mut s = t!(TcpStream::connect(&addr)); + t!(s.shutdown(Shutdown::Write)); + assert!(s.write(&[1]).is_err()); + let mut b = [0, 0]; + assert_eq!(t!(s.read(&mut b)), 1); + assert_eq!(b[0], 1); + }) +} + +#[test] +// FIXME: https://github.com/fortanix/rust-sgx/issues/110 +#[cfg_attr(target_env = "sgx", ignore)] +fn close_readwrite_smoke() { + each_ip(&mut |addr| { + let a = t!(TcpListener::bind(&addr)); + let (tx, rx) = channel::<()>(); + let _t = thread::spawn(move || { + let _s = t!(a.accept()); + let _ = rx.recv(); + }); + + let mut b = [0]; + let mut s = t!(TcpStream::connect(&addr)); + let mut s2 = t!(s.try_clone()); + + // closing should prevent reads/writes + t!(s.shutdown(Shutdown::Write)); + assert!(s.write(&[0]).is_err()); + t!(s.shutdown(Shutdown::Read)); + assert_eq!(s.read(&mut b).unwrap(), 0); + + // closing should affect previous handles + assert!(s2.write(&[0]).is_err()); + assert_eq!(s2.read(&mut b).unwrap(), 0); + + // closing should affect new handles + let mut s3 = t!(s.try_clone()); + assert!(s3.write(&[0]).is_err()); + assert_eq!(s3.read(&mut b).unwrap(), 0); + + // make sure these don't die + let _ = s2.shutdown(Shutdown::Read); + let _ = s2.shutdown(Shutdown::Write); + let _ = s3.shutdown(Shutdown::Read); + let _ = s3.shutdown(Shutdown::Write); + drop(tx); + }) +} + +#[test] +#[cfg(unix)] // test doesn't work on Windows, see #31657 +fn close_read_wakes_up() { + each_ip(&mut |addr| { + let a = t!(TcpListener::bind(&addr)); + let (tx1, rx) = channel::<()>(); + let _t = thread::spawn(move || { + let _s = t!(a.accept()); + let _ = rx.recv(); + }); + + let s = t!(TcpStream::connect(&addr)); + let s2 = t!(s.try_clone()); + let (tx, rx) = channel(); + let _t = thread::spawn(move || { + let mut s2 = s2; + assert_eq!(t!(s2.read(&mut [0])), 0); + tx.send(()).unwrap(); + }); + // this should wake up the child thread + t!(s.shutdown(Shutdown::Read)); + + // this test will never finish if the child doesn't wake up + rx.recv().unwrap(); + drop(tx1); + }) +} + +#[test] +fn clone_while_reading() { + each_ip(&mut |addr| { + let accept = t!(TcpListener::bind(&addr)); + + // Enqueue a thread to write to a socket + let (tx, rx) = channel(); + let (txdone, rxdone) = channel(); + let txdone2 = txdone.clone(); + let _t = thread::spawn(move || { + let mut tcp = t!(TcpStream::connect(&addr)); + rx.recv().unwrap(); + t!(tcp.write(&[0])); + txdone2.send(()).unwrap(); + }); + + // Spawn off a reading clone + let tcp = t!(accept.accept()).0; + let tcp2 = t!(tcp.try_clone()); + let txdone3 = txdone.clone(); + let _t = thread::spawn(move || { + let mut tcp2 = tcp2; + t!(tcp2.read(&mut [0])); + txdone3.send(()).unwrap(); + }); + + // Try to ensure that the reading clone is indeed reading + for _ in 0..50 { + thread::yield_now(); + } + + // clone the handle again while it's reading, then let it finish the + // read. + let _ = t!(tcp.try_clone()); + tx.send(()).unwrap(); + rxdone.recv().unwrap(); + rxdone.recv().unwrap(); + }) +} + +#[test] +fn clone_accept_smoke() { + each_ip(&mut |addr| { + let a = t!(TcpListener::bind(&addr)); + let a2 = t!(a.try_clone()); + + let _t = thread::spawn(move || { + let _ = TcpStream::connect(&addr); + }); + let _t = thread::spawn(move || { + let _ = TcpStream::connect(&addr); + }); + + t!(a.accept()); + t!(a2.accept()); + }) +} + +#[test] +fn clone_accept_concurrent() { + each_ip(&mut |addr| { + let a = t!(TcpListener::bind(&addr)); + let a2 = t!(a.try_clone()); + + let (tx, rx) = channel(); + let tx2 = tx.clone(); + + let _t = thread::spawn(move || { + tx.send(t!(a.accept())).unwrap(); + }); + let _t = thread::spawn(move || { + tx2.send(t!(a2.accept())).unwrap(); + }); + + let _t = thread::spawn(move || { + let _ = TcpStream::connect(&addr); + }); + let _t = thread::spawn(move || { + let _ = TcpStream::connect(&addr); + }); + + rx.recv().unwrap(); + rx.recv().unwrap(); + }) +} + +#[test] +fn debug() { + #[cfg(not(target_env = "sgx"))] + fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a { + addr + } + #[cfg(target_env = "sgx")] + fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a { + addr.to_string() + } + + #[cfg(target_env = "sgx")] + use crate::os::fortanix_sgx::io::AsRawFd; + #[cfg(unix)] + use crate::os::unix::io::AsRawFd; + #[cfg(not(windows))] + fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug { + addr.as_raw_fd() + } + #[cfg(windows)] + fn render_inner(addr: &dyn crate::os::windows::io::AsRawSocket) -> impl fmt::Debug { + addr.as_raw_socket() + } + + let inner_name = if cfg!(windows) { "socket" } else { "fd" }; + let socket_addr = next_test_ip4(); + + let listener = t!(TcpListener::bind(&socket_addr)); + let compare = format!( + "TcpListener {{ addr: {:?}, {}: {:?} }}", + render_socket_addr(&socket_addr), + inner_name, + render_inner(&listener) + ); + assert_eq!(format!("{:?}", listener), compare); + + let stream = t!(TcpStream::connect(&("localhost", socket_addr.port()))); + let compare = format!( + "TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}", + render_socket_addr(&stream.local_addr().unwrap()), + render_socket_addr(&stream.peer_addr().unwrap()), + inner_name, + render_inner(&stream) + ); + assert_eq!(format!("{:?}", stream), compare); +} + +// FIXME: re-enabled openbsd tests once their socket timeout code +// no longer has rounding errors. +// VxWorks ignores SO_SNDTIMEO. +#[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)] +#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 +#[test] +fn timeouts() { + let addr = next_test_ip4(); + let listener = t!(TcpListener::bind(&addr)); + + let stream = t!(TcpStream::connect(&("localhost", addr.port()))); + let dur = Duration::new(15410, 0); + + assert_eq!(None, t!(stream.read_timeout())); + + t!(stream.set_read_timeout(Some(dur))); + assert_eq!(Some(dur), t!(stream.read_timeout())); + + assert_eq!(None, t!(stream.write_timeout())); + + t!(stream.set_write_timeout(Some(dur))); + assert_eq!(Some(dur), t!(stream.write_timeout())); + + t!(stream.set_read_timeout(None)); + assert_eq!(None, t!(stream.read_timeout())); + + t!(stream.set_write_timeout(None)); + assert_eq!(None, t!(stream.write_timeout())); + drop(listener); +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 +fn test_read_timeout() { + let addr = next_test_ip4(); + let listener = t!(TcpListener::bind(&addr)); + + let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); + t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut buf = [0; 10]; + let start = Instant::now(); + let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); + assert!( + kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", + kind + ); + assert!(start.elapsed() > Duration::from_millis(400)); + drop(listener); +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 +fn test_read_with_timeout() { + let addr = next_test_ip4(); + let listener = t!(TcpListener::bind(&addr)); + + let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); + t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut other_end = t!(listener.accept()).0; + t!(other_end.write_all(b"hello world")); + + let mut buf = [0; 11]; + t!(stream.read(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + + let start = Instant::now(); + let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); + assert!( + kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", + kind + ); + assert!(start.elapsed() > Duration::from_millis(400)); + drop(listener); +} + +// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors +// when passed zero Durations +#[test] +fn test_timeout_zero_duration() { + let addr = next_test_ip4(); + + let listener = t!(TcpListener::bind(&addr)); + let stream = t!(TcpStream::connect(&addr)); + + let result = stream.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = stream.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + drop(listener); +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] +fn nodelay() { + let addr = next_test_ip4(); + let _listener = t!(TcpListener::bind(&addr)); + + let stream = t!(TcpStream::connect(&("localhost", addr.port()))); + + assert_eq!(false, t!(stream.nodelay())); + t!(stream.set_nodelay(true)); + assert_eq!(true, t!(stream.nodelay())); + t!(stream.set_nodelay(false)); + assert_eq!(false, t!(stream.nodelay())); +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] +fn ttl() { + let ttl = 100; + + let addr = next_test_ip4(); + let listener = t!(TcpListener::bind(&addr)); + + t!(listener.set_ttl(ttl)); + assert_eq!(ttl, t!(listener.ttl())); + + let stream = t!(TcpStream::connect(&("localhost", addr.port()))); + + t!(stream.set_ttl(ttl)); + assert_eq!(ttl, t!(stream.ttl())); +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] +fn set_nonblocking() { + let addr = next_test_ip4(); + let listener = t!(TcpListener::bind(&addr)); + + t!(listener.set_nonblocking(true)); + t!(listener.set_nonblocking(false)); + + let mut stream = t!(TcpStream::connect(&("localhost", addr.port()))); + + t!(stream.set_nonblocking(false)); + t!(stream.set_nonblocking(true)); + + let mut buf = [0]; + match stream.read(&mut buf) { + Ok(_) => panic!("expected error"), + Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} + Err(e) => panic!("unexpected error {}", e), + } +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 +fn peek() { + each_ip(&mut |addr| { + let (txdone, rxdone) = channel(); + + let srv = t!(TcpListener::bind(&addr)); + let _t = thread::spawn(move || { + let mut cl = t!(srv.accept()).0; + cl.write(&[1, 3, 3, 7]).unwrap(); + t!(rxdone.recv()); + }); + + let mut c = t!(TcpStream::connect(&addr)); + let mut b = [0; 10]; + for _ in 1..3 { + let len = c.peek(&mut b).unwrap(); + assert_eq!(len, 4); + } + let len = c.read(&mut b).unwrap(); + assert_eq!(len, 4); + + t!(c.set_nonblocking(true)); + match c.peek(&mut b) { + Ok(_) => panic!("expected error"), + Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} + Err(e) => panic!("unexpected error {}", e), + } + t!(txdone.send(())); + }) +} + +#[test] +#[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 +fn connect_timeout_valid() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + TcpStream::connect_timeout(&addr, Duration::from_secs(2)).unwrap(); +} diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs index d730b2b87ac..17e3e4497c4 100644 --- a/library/std/src/net/udp.rs +++ b/library/std/src/net/udp.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] +mod tests; + use crate::fmt; use crate::io::{self, Error, ErrorKind}; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs}; @@ -798,380 +801,3 @@ impl fmt::Debug for UdpSocket { self.0.fmt(f) } } - -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] -mod tests { - use crate::io::ErrorKind; - use crate::net::test::{next_test_ip4, next_test_ip6}; - use crate::net::*; - use crate::sync::mpsc::channel; - use crate::sys_common::AsInner; - use crate::thread; - use crate::time::{Duration, Instant}; - - fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) { - f(next_test_ip4(), next_test_ip4()); - f(next_test_ip6(), next_test_ip6()); - } - - macro_rules! t { - ($e:expr) => { - match $e { - Ok(t) => t, - Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), - } - }; - } - - #[test] - fn bind_error() { - match UdpSocket::bind("1.1.1.1:9999") { - Ok(..) => panic!(), - Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable), - } - } - - #[test] - fn socket_smoke_test_ip4() { - each_ip(&mut |server_ip, client_ip| { - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - - let _t = thread::spawn(move || { - let client = t!(UdpSocket::bind(&client_ip)); - rx1.recv().unwrap(); - t!(client.send_to(&[99], &server_ip)); - tx2.send(()).unwrap(); - }); - - let server = t!(UdpSocket::bind(&server_ip)); - tx1.send(()).unwrap(); - let mut buf = [0]; - let (nread, src) = t!(server.recv_from(&mut buf)); - assert_eq!(nread, 1); - assert_eq!(buf[0], 99); - assert_eq!(src, client_ip); - rx2.recv().unwrap(); - }) - } - - #[test] - fn socket_name() { - each_ip(&mut |addr, _| { - let server = t!(UdpSocket::bind(&addr)); - assert_eq!(addr, t!(server.local_addr())); - }) - } - - #[test] - fn socket_peer() { - each_ip(&mut |addr1, addr2| { - let server = t!(UdpSocket::bind(&addr1)); - assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected); - t!(server.connect(&addr2)); - assert_eq!(addr2, t!(server.peer_addr())); - }) - } - - #[test] - fn udp_clone_smoke() { - each_ip(&mut |addr1, addr2| { - let sock1 = t!(UdpSocket::bind(&addr1)); - let sock2 = t!(UdpSocket::bind(&addr2)); - - let _t = thread::spawn(move || { - let mut buf = [0, 0]; - assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1)); - assert_eq!(buf[0], 1); - t!(sock2.send_to(&[2], &addr1)); - }); - - let sock3 = t!(sock1.try_clone()); - - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - let _t = thread::spawn(move || { - rx1.recv().unwrap(); - t!(sock3.send_to(&[1], &addr2)); - tx2.send(()).unwrap(); - }); - tx1.send(()).unwrap(); - let mut buf = [0, 0]; - assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2)); - rx2.recv().unwrap(); - }) - } - - #[test] - fn udp_clone_two_read() { - each_ip(&mut |addr1, addr2| { - let sock1 = t!(UdpSocket::bind(&addr1)); - let sock2 = t!(UdpSocket::bind(&addr2)); - let (tx1, rx) = channel(); - let tx2 = tx1.clone(); - - let _t = thread::spawn(move || { - t!(sock2.send_to(&[1], &addr1)); - rx.recv().unwrap(); - t!(sock2.send_to(&[2], &addr1)); - rx.recv().unwrap(); - }); - - let sock3 = t!(sock1.try_clone()); - - let (done, rx) = channel(); - let _t = thread::spawn(move || { - let mut buf = [0, 0]; - t!(sock3.recv_from(&mut buf)); - tx2.send(()).unwrap(); - done.send(()).unwrap(); - }); - let mut buf = [0, 0]; - t!(sock1.recv_from(&mut buf)); - tx1.send(()).unwrap(); - - rx.recv().unwrap(); - }) - } - - #[test] - fn udp_clone_two_write() { - each_ip(&mut |addr1, addr2| { - let sock1 = t!(UdpSocket::bind(&addr1)); - let sock2 = t!(UdpSocket::bind(&addr2)); - - let (tx, rx) = channel(); - let (serv_tx, serv_rx) = channel(); - - let _t = thread::spawn(move || { - let mut buf = [0, 1]; - rx.recv().unwrap(); - t!(sock2.recv_from(&mut buf)); - serv_tx.send(()).unwrap(); - }); - - let sock3 = t!(sock1.try_clone()); - - let (done, rx) = channel(); - let tx2 = tx.clone(); - let _t = thread::spawn(move || { - match sock3.send_to(&[1], &addr2) { - Ok(..) => { - let _ = tx2.send(()); - } - Err(..) => {} - } - done.send(()).unwrap(); - }); - match sock1.send_to(&[2], &addr2) { - Ok(..) => { - let _ = tx.send(()); - } - Err(..) => {} - } - drop(tx); - - rx.recv().unwrap(); - serv_rx.recv().unwrap(); - }) - } - - #[test] - fn debug() { - let name = if cfg!(windows) { "socket" } else { "fd" }; - let socket_addr = next_test_ip4(); - - let udpsock = t!(UdpSocket::bind(&socket_addr)); - let udpsock_inner = udpsock.0.socket().as_inner(); - let compare = - format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", socket_addr, name, udpsock_inner); - assert_eq!(format!("{:?}", udpsock), compare); - } - - // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code - // no longer has rounding errors. - // VxWorks ignores SO_SNDTIMEO. - #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)] - #[test] - fn timeouts() { - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); - let dur = Duration::new(15410, 0); - - assert_eq!(None, t!(stream.read_timeout())); - - t!(stream.set_read_timeout(Some(dur))); - assert_eq!(Some(dur), t!(stream.read_timeout())); - - assert_eq!(None, t!(stream.write_timeout())); - - t!(stream.set_write_timeout(Some(dur))); - assert_eq!(Some(dur), t!(stream.write_timeout())); - - t!(stream.set_read_timeout(None)); - assert_eq!(None, t!(stream.read_timeout())); - - t!(stream.set_write_timeout(None)); - assert_eq!(None, t!(stream.write_timeout())); - } - - #[test] - fn test_read_timeout() { - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); - - let mut buf = [0; 10]; - - let start = Instant::now(); - loop { - let kind = stream.recv_from(&mut buf).err().expect("expected error").kind(); - if kind != ErrorKind::Interrupted { - assert!( - kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, - "unexpected_error: {:?}", - kind - ); - break; - } - } - assert!(start.elapsed() > Duration::from_millis(400)); - } - - #[test] - fn test_read_with_timeout() { - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); - t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); - - t!(stream.send_to(b"hello world", &addr)); - - let mut buf = [0; 11]; - t!(stream.recv_from(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - - let start = Instant::now(); - loop { - let kind = stream.recv_from(&mut buf).err().expect("expected error").kind(); - if kind != ErrorKind::Interrupted { - assert!( - kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, - "unexpected_error: {:?}", - kind - ); - break; - } - } - assert!(start.elapsed() > Duration::from_millis(400)); - } - - // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors - // when passed zero Durations - #[test] - fn test_timeout_zero_duration() { - let addr = next_test_ip4(); - - let socket = t!(UdpSocket::bind(&addr)); - - let result = socket.set_write_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - - let result = socket.set_read_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - } - - #[test] - fn connect_send_recv() { - let addr = next_test_ip4(); - - let socket = t!(UdpSocket::bind(&addr)); - t!(socket.connect(addr)); - - t!(socket.send(b"hello world")); - - let mut buf = [0; 11]; - t!(socket.recv(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - } - - #[test] - fn connect_send_peek_recv() { - each_ip(&mut |addr, _| { - let socket = t!(UdpSocket::bind(&addr)); - t!(socket.connect(addr)); - - t!(socket.send(b"hello world")); - - for _ in 1..3 { - let mut buf = [0; 11]; - let size = t!(socket.peek(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - assert_eq!(size, 11); - } - - let mut buf = [0; 11]; - let size = t!(socket.recv(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - assert_eq!(size, 11); - }) - } - - #[test] - fn peek_from() { - each_ip(&mut |addr, _| { - let socket = t!(UdpSocket::bind(&addr)); - t!(socket.send_to(b"hello world", &addr)); - - for _ in 1..3 { - let mut buf = [0; 11]; - let (size, _) = t!(socket.peek_from(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - assert_eq!(size, 11); - } - - let mut buf = [0; 11]; - let (size, _) = t!(socket.recv_from(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - assert_eq!(size, 11); - }) - } - - #[test] - fn ttl() { - let ttl = 100; - - let addr = next_test_ip4(); - - let stream = t!(UdpSocket::bind(&addr)); - - t!(stream.set_ttl(ttl)); - assert_eq!(ttl, t!(stream.ttl())); - } - - #[test] - fn set_nonblocking() { - each_ip(&mut |addr, _| { - let socket = t!(UdpSocket::bind(&addr)); - - t!(socket.set_nonblocking(true)); - t!(socket.set_nonblocking(false)); - - t!(socket.connect(addr)); - - t!(socket.set_nonblocking(false)); - t!(socket.set_nonblocking(true)); - - let mut buf = [0]; - match socket.recv(&mut buf) { - Ok(_) => panic!("expected error"), - Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} - Err(e) => panic!("unexpected error {}", e), - } - }) - } -} diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs new file mode 100644 index 00000000000..658369f79aa --- /dev/null +++ b/library/std/src/net/udp/tests.rs @@ -0,0 +1,372 @@ +use crate::io::ErrorKind; +use crate::net::test::{next_test_ip4, next_test_ip6}; +use crate::net::*; +use crate::sync::mpsc::channel; +use crate::sys_common::AsInner; +use crate::thread; +use crate::time::{Duration, Instant}; + +fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) { + f(next_test_ip4(), next_test_ip4()); + f(next_test_ip6(), next_test_ip6()); +} + +macro_rules! t { + ($e:expr) => { + match $e { + Ok(t) => t, + Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), + } + }; +} + +#[test] +fn bind_error() { + match UdpSocket::bind("1.1.1.1:9999") { + Ok(..) => panic!(), + Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable), + } +} + +#[test] +fn socket_smoke_test_ip4() { + each_ip(&mut |server_ip, client_ip| { + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + + let _t = thread::spawn(move || { + let client = t!(UdpSocket::bind(&client_ip)); + rx1.recv().unwrap(); + t!(client.send_to(&[99], &server_ip)); + tx2.send(()).unwrap(); + }); + + let server = t!(UdpSocket::bind(&server_ip)); + tx1.send(()).unwrap(); + let mut buf = [0]; + let (nread, src) = t!(server.recv_from(&mut buf)); + assert_eq!(nread, 1); + assert_eq!(buf[0], 99); + assert_eq!(src, client_ip); + rx2.recv().unwrap(); + }) +} + +#[test] +fn socket_name() { + each_ip(&mut |addr, _| { + let server = t!(UdpSocket::bind(&addr)); + assert_eq!(addr, t!(server.local_addr())); + }) +} + +#[test] +fn socket_peer() { + each_ip(&mut |addr1, addr2| { + let server = t!(UdpSocket::bind(&addr1)); + assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected); + t!(server.connect(&addr2)); + assert_eq!(addr2, t!(server.peer_addr())); + }) +} + +#[test] +fn udp_clone_smoke() { + each_ip(&mut |addr1, addr2| { + let sock1 = t!(UdpSocket::bind(&addr1)); + let sock2 = t!(UdpSocket::bind(&addr2)); + + let _t = thread::spawn(move || { + let mut buf = [0, 0]; + assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1)); + assert_eq!(buf[0], 1); + t!(sock2.send_to(&[2], &addr1)); + }); + + let sock3 = t!(sock1.try_clone()); + + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + let _t = thread::spawn(move || { + rx1.recv().unwrap(); + t!(sock3.send_to(&[1], &addr2)); + tx2.send(()).unwrap(); + }); + tx1.send(()).unwrap(); + let mut buf = [0, 0]; + assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2)); + rx2.recv().unwrap(); + }) +} + +#[test] +fn udp_clone_two_read() { + each_ip(&mut |addr1, addr2| { + let sock1 = t!(UdpSocket::bind(&addr1)); + let sock2 = t!(UdpSocket::bind(&addr2)); + let (tx1, rx) = channel(); + let tx2 = tx1.clone(); + + let _t = thread::spawn(move || { + t!(sock2.send_to(&[1], &addr1)); + rx.recv().unwrap(); + t!(sock2.send_to(&[2], &addr1)); + rx.recv().unwrap(); + }); + + let sock3 = t!(sock1.try_clone()); + + let (done, rx) = channel(); + let _t = thread::spawn(move || { + let mut buf = [0, 0]; + t!(sock3.recv_from(&mut buf)); + tx2.send(()).unwrap(); + done.send(()).unwrap(); + }); + let mut buf = [0, 0]; + t!(sock1.recv_from(&mut buf)); + tx1.send(()).unwrap(); + + rx.recv().unwrap(); + }) +} + +#[test] +fn udp_clone_two_write() { + each_ip(&mut |addr1, addr2| { + let sock1 = t!(UdpSocket::bind(&addr1)); + let sock2 = t!(UdpSocket::bind(&addr2)); + + let (tx, rx) = channel(); + let (serv_tx, serv_rx) = channel(); + + let _t = thread::spawn(move || { + let mut buf = [0, 1]; + rx.recv().unwrap(); + t!(sock2.recv_from(&mut buf)); + serv_tx.send(()).unwrap(); + }); + + let sock3 = t!(sock1.try_clone()); + + let (done, rx) = channel(); + let tx2 = tx.clone(); + let _t = thread::spawn(move || { + match sock3.send_to(&[1], &addr2) { + Ok(..) => { + let _ = tx2.send(()); + } + Err(..) => {} + } + done.send(()).unwrap(); + }); + match sock1.send_to(&[2], &addr2) { + Ok(..) => { + let _ = tx.send(()); + } + Err(..) => {} + } + drop(tx); + + rx.recv().unwrap(); + serv_rx.recv().unwrap(); + }) +} + +#[test] +fn debug() { + let name = if cfg!(windows) { "socket" } else { "fd" }; + let socket_addr = next_test_ip4(); + + let udpsock = t!(UdpSocket::bind(&socket_addr)); + let udpsock_inner = udpsock.0.socket().as_inner(); + let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", socket_addr, name, udpsock_inner); + assert_eq!(format!("{:?}", udpsock), compare); +} + +// FIXME: re-enabled openbsd/netbsd tests once their socket timeout code +// no longer has rounding errors. +// VxWorks ignores SO_SNDTIMEO. +#[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)] +#[test] +fn timeouts() { + let addr = next_test_ip4(); + + let stream = t!(UdpSocket::bind(&addr)); + let dur = Duration::new(15410, 0); + + assert_eq!(None, t!(stream.read_timeout())); + + t!(stream.set_read_timeout(Some(dur))); + assert_eq!(Some(dur), t!(stream.read_timeout())); + + assert_eq!(None, t!(stream.write_timeout())); + + t!(stream.set_write_timeout(Some(dur))); + assert_eq!(Some(dur), t!(stream.write_timeout())); + + t!(stream.set_read_timeout(None)); + assert_eq!(None, t!(stream.read_timeout())); + + t!(stream.set_write_timeout(None)); + assert_eq!(None, t!(stream.write_timeout())); +} + +#[test] +fn test_read_timeout() { + let addr = next_test_ip4(); + + let stream = t!(UdpSocket::bind(&addr)); + t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut buf = [0; 10]; + + let start = Instant::now(); + loop { + let kind = stream.recv_from(&mut buf).err().expect("expected error").kind(); + if kind != ErrorKind::Interrupted { + assert!( + kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", + kind + ); + break; + } + } + assert!(start.elapsed() > Duration::from_millis(400)); +} + +#[test] +fn test_read_with_timeout() { + let addr = next_test_ip4(); + + let stream = t!(UdpSocket::bind(&addr)); + t!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + t!(stream.send_to(b"hello world", &addr)); + + let mut buf = [0; 11]; + t!(stream.recv_from(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + + let start = Instant::now(); + loop { + let kind = stream.recv_from(&mut buf).err().expect("expected error").kind(); + if kind != ErrorKind::Interrupted { + assert!( + kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", + kind + ); + break; + } + } + assert!(start.elapsed() > Duration::from_millis(400)); +} + +// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors +// when passed zero Durations +#[test] +fn test_timeout_zero_duration() { + let addr = next_test_ip4(); + + let socket = t!(UdpSocket::bind(&addr)); + + let result = socket.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = socket.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); +} + +#[test] +fn connect_send_recv() { + let addr = next_test_ip4(); + + let socket = t!(UdpSocket::bind(&addr)); + t!(socket.connect(addr)); + + t!(socket.send(b"hello world")); + + let mut buf = [0; 11]; + t!(socket.recv(&mut buf)); + assert_eq!(b"hello world", &buf[..]); +} + +#[test] +fn connect_send_peek_recv() { + each_ip(&mut |addr, _| { + let socket = t!(UdpSocket::bind(&addr)); + t!(socket.connect(addr)); + + t!(socket.send(b"hello world")); + + for _ in 1..3 { + let mut buf = [0; 11]; + let size = t!(socket.peek(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + assert_eq!(size, 11); + } + + let mut buf = [0; 11]; + let size = t!(socket.recv(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + assert_eq!(size, 11); + }) +} + +#[test] +fn peek_from() { + each_ip(&mut |addr, _| { + let socket = t!(UdpSocket::bind(&addr)); + t!(socket.send_to(b"hello world", &addr)); + + for _ in 1..3 { + let mut buf = [0; 11]; + let (size, _) = t!(socket.peek_from(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + assert_eq!(size, 11); + } + + let mut buf = [0; 11]; + let (size, _) = t!(socket.recv_from(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + assert_eq!(size, 11); + }) +} + +#[test] +fn ttl() { + let ttl = 100; + + let addr = next_test_ip4(); + + let stream = t!(UdpSocket::bind(&addr)); + + t!(stream.set_ttl(ttl)); + assert_eq!(ttl, t!(stream.ttl())); +} + +#[test] +fn set_nonblocking() { + each_ip(&mut |addr, _| { + let socket = t!(UdpSocket::bind(&addr)); + + t!(socket.set_nonblocking(true)); + t!(socket.set_nonblocking(false)); + + t!(socket.connect(addr)); + + t!(socket.set_nonblocking(false)); + t!(socket.set_nonblocking(true)); + + let mut buf = [0]; + match socket.recv(&mut buf) { + Ok(_) => panic!("expected error"), + Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} + Err(e) => panic!("unexpected error {}", e), + } + }) +} diff --git a/library/std/src/num.rs b/library/std/src/num.rs index b496c16a749..0f1c5962685 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -6,6 +6,12 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] +#[cfg(test)] +mod tests; + +#[cfg(test)] +mod benches; + #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; #[stable(feature = "rust1", since = "1.0.0")] @@ -48,250 +54,3 @@ where assert_eq!(ten.div(two), ten / two); assert_eq!(ten.rem(two), ten % two); } - -#[cfg(test)] -mod tests { - use crate::ops::Mul; - - #[test] - fn test_saturating_add_uint() { - assert_eq!(3_usize.saturating_add(5_usize), 8_usize); - assert_eq!(3_usize.saturating_add(usize::MAX - 1), usize::MAX); - assert_eq!(usize::MAX.saturating_add(usize::MAX), usize::MAX); - assert_eq!((usize::MAX - 2).saturating_add(1), usize::MAX - 1); - } - - #[test] - fn test_saturating_sub_uint() { - assert_eq!(5_usize.saturating_sub(3_usize), 2_usize); - assert_eq!(3_usize.saturating_sub(5_usize), 0_usize); - assert_eq!(0_usize.saturating_sub(1_usize), 0_usize); - assert_eq!((usize::MAX - 1).saturating_sub(usize::MAX), 0); - } - - #[test] - fn test_saturating_add_int() { - assert_eq!(3i32.saturating_add(5), 8); - assert_eq!(3isize.saturating_add(isize::MAX - 1), isize::MAX); - assert_eq!(isize::MAX.saturating_add(isize::MAX), isize::MAX); - assert_eq!((isize::MAX - 2).saturating_add(1), isize::MAX - 1); - assert_eq!(3i32.saturating_add(-5), -2); - assert_eq!(isize::MIN.saturating_add(-1), isize::MIN); - assert_eq!((-2isize).saturating_add(-isize::MAX), isize::MIN); - } - - #[test] - fn test_saturating_sub_int() { - assert_eq!(3i32.saturating_sub(5), -2); - assert_eq!(isize::MIN.saturating_sub(1), isize::MIN); - assert_eq!((-2isize).saturating_sub(isize::MAX), isize::MIN); - assert_eq!(3i32.saturating_sub(-5), 8); - assert_eq!(3isize.saturating_sub(-(isize::MAX - 1)), isize::MAX); - assert_eq!(isize::MAX.saturating_sub(-isize::MAX), isize::MAX); - assert_eq!((isize::MAX - 2).saturating_sub(-1), isize::MAX - 1); - } - - #[test] - fn test_checked_add() { - let five_less = usize::MAX - 5; - assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5)); - assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4)); - assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3)); - assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2)); - assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1)); - assert_eq!(five_less.checked_add(5), Some(usize::MAX)); - assert_eq!(five_less.checked_add(6), None); - assert_eq!(five_less.checked_add(7), None); - } - - #[test] - fn test_checked_sub() { - assert_eq!(5_usize.checked_sub(0), Some(5)); - assert_eq!(5_usize.checked_sub(1), Some(4)); - assert_eq!(5_usize.checked_sub(2), Some(3)); - assert_eq!(5_usize.checked_sub(3), Some(2)); - assert_eq!(5_usize.checked_sub(4), Some(1)); - assert_eq!(5_usize.checked_sub(5), Some(0)); - assert_eq!(5_usize.checked_sub(6), None); - assert_eq!(5_usize.checked_sub(7), None); - } - - #[test] - fn test_checked_mul() { - let third = usize::MAX / 3; - assert_eq!(third.checked_mul(0), Some(0)); - assert_eq!(third.checked_mul(1), Some(third)); - assert_eq!(third.checked_mul(2), Some(third * 2)); - assert_eq!(third.checked_mul(3), Some(third * 3)); - assert_eq!(third.checked_mul(4), None); - } - - macro_rules! test_is_power_of_two { - ($test_name:ident, $T:ident) => { - fn $test_name() { - #![test] - assert_eq!((0 as $T).is_power_of_two(), false); - assert_eq!((1 as $T).is_power_of_two(), true); - assert_eq!((2 as $T).is_power_of_two(), true); - assert_eq!((3 as $T).is_power_of_two(), false); - assert_eq!((4 as $T).is_power_of_two(), true); - assert_eq!((5 as $T).is_power_of_two(), false); - assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true); - } - }; - } - - test_is_power_of_two! { test_is_power_of_two_u8, u8 } - test_is_power_of_two! { test_is_power_of_two_u16, u16 } - test_is_power_of_two! { test_is_power_of_two_u32, u32 } - test_is_power_of_two! { test_is_power_of_two_u64, u64 } - test_is_power_of_two! { test_is_power_of_two_uint, usize } - - macro_rules! test_next_power_of_two { - ($test_name:ident, $T:ident) => { - fn $test_name() { - #![test] - assert_eq!((0 as $T).next_power_of_two(), 1); - let mut next_power = 1; - for i in 1 as $T..40 { - assert_eq!(i.next_power_of_two(), next_power); - if i == next_power { - next_power *= 2 - } - } - } - }; - } - - test_next_power_of_two! { test_next_power_of_two_u8, u8 } - test_next_power_of_two! { test_next_power_of_two_u16, u16 } - test_next_power_of_two! { test_next_power_of_two_u32, u32 } - test_next_power_of_two! { test_next_power_of_two_u64, u64 } - test_next_power_of_two! { test_next_power_of_two_uint, usize } - - macro_rules! test_checked_next_power_of_two { - ($test_name:ident, $T:ident) => { - fn $test_name() { - #![test] - assert_eq!((0 as $T).checked_next_power_of_two(), Some(1)); - let smax = $T::MAX >> 1; - assert_eq!(smax.checked_next_power_of_two(), Some(smax + 1)); - assert_eq!((smax + 1).checked_next_power_of_two(), Some(smax + 1)); - assert_eq!((smax + 2).checked_next_power_of_two(), None); - assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None); - assert_eq!($T::MAX.checked_next_power_of_two(), None); - let mut next_power = 1; - for i in 1 as $T..40 { - assert_eq!(i.checked_next_power_of_two(), Some(next_power)); - if i == next_power { - next_power *= 2 - } - } - } - }; - } - - test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 } - test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 } - test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 } - test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 } - test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize } - - #[test] - fn test_pow() { - fn naive_pow<T: Mul<Output = T> + Copy>(one: T, base: T, exp: usize) -> T { - (0..exp).fold(one, |acc, _| acc * base) - } - macro_rules! assert_pow { - (($num:expr, $exp:expr) => $expected:expr) => {{ - let result = $num.pow($exp); - assert_eq!(result, $expected); - assert_eq!(result, naive_pow(1, $num, $exp)); - }}; - } - assert_pow!((3u32, 0 ) => 1); - assert_pow!((5u32, 1 ) => 5); - assert_pow!((-4i32, 2 ) => 16); - assert_pow!((8u32, 3 ) => 512); - assert_pow!((2u64, 50) => 1125899906842624); - } - - #[test] - fn test_uint_to_str_overflow() { - let mut u8_val: u8 = 255; - assert_eq!(u8_val.to_string(), "255"); - - u8_val = u8_val.wrapping_add(1); - assert_eq!(u8_val.to_string(), "0"); - - let mut u16_val: u16 = 65_535; - assert_eq!(u16_val.to_string(), "65535"); - - u16_val = u16_val.wrapping_add(1); - assert_eq!(u16_val.to_string(), "0"); - - let mut u32_val: u32 = 4_294_967_295; - assert_eq!(u32_val.to_string(), "4294967295"); - - u32_val = u32_val.wrapping_add(1); - assert_eq!(u32_val.to_string(), "0"); - - let mut u64_val: u64 = 18_446_744_073_709_551_615; - assert_eq!(u64_val.to_string(), "18446744073709551615"); - - u64_val = u64_val.wrapping_add(1); - assert_eq!(u64_val.to_string(), "0"); - } - - fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> { - crate::str::FromStr::from_str(t).ok() - } - - #[test] - fn test_uint_from_str_overflow() { - let mut u8_val: u8 = 255; - assert_eq!(from_str::<u8>("255"), Some(u8_val)); - assert_eq!(from_str::<u8>("256"), None); - - u8_val = u8_val.wrapping_add(1); - assert_eq!(from_str::<u8>("0"), Some(u8_val)); - assert_eq!(from_str::<u8>("-1"), None); - - let mut u16_val: u16 = 65_535; - assert_eq!(from_str::<u16>("65535"), Some(u16_val)); - assert_eq!(from_str::<u16>("65536"), None); - - u16_val = u16_val.wrapping_add(1); - assert_eq!(from_str::<u16>("0"), Some(u16_val)); - assert_eq!(from_str::<u16>("-1"), None); - - let mut u32_val: u32 = 4_294_967_295; - assert_eq!(from_str::<u32>("4294967295"), Some(u32_val)); - assert_eq!(from_str::<u32>("4294967296"), None); - - u32_val = u32_val.wrapping_add(1); - assert_eq!(from_str::<u32>("0"), Some(u32_val)); - assert_eq!(from_str::<u32>("-1"), None); - - let mut u64_val: u64 = 18_446_744_073_709_551_615; - assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val)); - assert_eq!(from_str::<u64>("18446744073709551616"), None); - - u64_val = u64_val.wrapping_add(1); - assert_eq!(from_str::<u64>("0"), Some(u64_val)); - assert_eq!(from_str::<u64>("-1"), None); - } -} - -#[cfg(test)] -mod bench { - use test::Bencher; - - #[bench] - fn bench_pow_function(b: &mut Bencher) { - let v = (0..1024).collect::<Vec<u32>>(); - b.iter(|| { - v.iter().fold(0u32, |old, new| old.pow(*new as u32)); - }); - } -} diff --git a/library/std/src/num/benches.rs b/library/std/src/num/benches.rs new file mode 100644 index 00000000000..233ea0506c0 --- /dev/null +++ b/library/std/src/num/benches.rs @@ -0,0 +1,9 @@ +use test::Bencher; + +#[bench] +fn bench_pow_function(b: &mut Bencher) { + let v = (0..1024).collect::<Vec<u32>>(); + b.iter(|| { + v.iter().fold(0u32, |old, new| old.pow(*new as u32)); + }); +} diff --git a/library/std/src/num/tests.rs b/library/std/src/num/tests.rs new file mode 100644 index 00000000000..2f50b73f490 --- /dev/null +++ b/library/std/src/num/tests.rs @@ -0,0 +1,230 @@ +use crate::ops::Mul; + +#[test] +fn test_saturating_add_uint() { + assert_eq!(3_usize.saturating_add(5_usize), 8_usize); + assert_eq!(3_usize.saturating_add(usize::MAX - 1), usize::MAX); + assert_eq!(usize::MAX.saturating_add(usize::MAX), usize::MAX); + assert_eq!((usize::MAX - 2).saturating_add(1), usize::MAX - 1); +} + +#[test] +fn test_saturating_sub_uint() { + assert_eq!(5_usize.saturating_sub(3_usize), 2_usize); + assert_eq!(3_usize.saturating_sub(5_usize), 0_usize); + assert_eq!(0_usize.saturating_sub(1_usize), 0_usize); + assert_eq!((usize::MAX - 1).saturating_sub(usize::MAX), 0); +} + +#[test] +fn test_saturating_add_int() { + assert_eq!(3i32.saturating_add(5), 8); + assert_eq!(3isize.saturating_add(isize::MAX - 1), isize::MAX); + assert_eq!(isize::MAX.saturating_add(isize::MAX), isize::MAX); + assert_eq!((isize::MAX - 2).saturating_add(1), isize::MAX - 1); + assert_eq!(3i32.saturating_add(-5), -2); + assert_eq!(isize::MIN.saturating_add(-1), isize::MIN); + assert_eq!((-2isize).saturating_add(-isize::MAX), isize::MIN); +} + +#[test] +fn test_saturating_sub_int() { + assert_eq!(3i32.saturating_sub(5), -2); + assert_eq!(isize::MIN.saturating_sub(1), isize::MIN); + assert_eq!((-2isize).saturating_sub(isize::MAX), isize::MIN); + assert_eq!(3i32.saturating_sub(-5), 8); + assert_eq!(3isize.saturating_sub(-(isize::MAX - 1)), isize::MAX); + assert_eq!(isize::MAX.saturating_sub(-isize::MAX), isize::MAX); + assert_eq!((isize::MAX - 2).saturating_sub(-1), isize::MAX - 1); +} + +#[test] +fn test_checked_add() { + let five_less = usize::MAX - 5; + assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5)); + assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4)); + assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3)); + assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2)); + assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1)); + assert_eq!(five_less.checked_add(5), Some(usize::MAX)); + assert_eq!(five_less.checked_add(6), None); + assert_eq!(five_less.checked_add(7), None); +} + +#[test] +fn test_checked_sub() { + assert_eq!(5_usize.checked_sub(0), Some(5)); + assert_eq!(5_usize.checked_sub(1), Some(4)); + assert_eq!(5_usize.checked_sub(2), Some(3)); + assert_eq!(5_usize.checked_sub(3), Some(2)); + assert_eq!(5_usize.checked_sub(4), Some(1)); + assert_eq!(5_usize.checked_sub(5), Some(0)); + assert_eq!(5_usize.checked_sub(6), None); + assert_eq!(5_usize.checked_sub(7), None); +} + +#[test] +fn test_checked_mul() { + let third = usize::MAX / 3; + assert_eq!(third.checked_mul(0), Some(0)); + assert_eq!(third.checked_mul(1), Some(third)); + assert_eq!(third.checked_mul(2), Some(third * 2)); + assert_eq!(third.checked_mul(3), Some(third * 3)); + assert_eq!(third.checked_mul(4), None); +} + +macro_rules! test_is_power_of_two { + ($test_name:ident, $T:ident) => { + fn $test_name() { + #![test] + assert_eq!((0 as $T).is_power_of_two(), false); + assert_eq!((1 as $T).is_power_of_two(), true); + assert_eq!((2 as $T).is_power_of_two(), true); + assert_eq!((3 as $T).is_power_of_two(), false); + assert_eq!((4 as $T).is_power_of_two(), true); + assert_eq!((5 as $T).is_power_of_two(), false); + assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true); + } + }; +} + +test_is_power_of_two! { test_is_power_of_two_u8, u8 } +test_is_power_of_two! { test_is_power_of_two_u16, u16 } +test_is_power_of_two! { test_is_power_of_two_u32, u32 } +test_is_power_of_two! { test_is_power_of_two_u64, u64 } +test_is_power_of_two! { test_is_power_of_two_uint, usize } + +macro_rules! test_next_power_of_two { + ($test_name:ident, $T:ident) => { + fn $test_name() { + #![test] + assert_eq!((0 as $T).next_power_of_two(), 1); + let mut next_power = 1; + for i in 1 as $T..40 { + assert_eq!(i.next_power_of_two(), next_power); + if i == next_power { + next_power *= 2 + } + } + } + }; +} + +test_next_power_of_two! { test_next_power_of_two_u8, u8 } +test_next_power_of_two! { test_next_power_of_two_u16, u16 } +test_next_power_of_two! { test_next_power_of_two_u32, u32 } +test_next_power_of_two! { test_next_power_of_two_u64, u64 } +test_next_power_of_two! { test_next_power_of_two_uint, usize } + +macro_rules! test_checked_next_power_of_two { + ($test_name:ident, $T:ident) => { + fn $test_name() { + #![test] + assert_eq!((0 as $T).checked_next_power_of_two(), Some(1)); + let smax = $T::MAX >> 1; + assert_eq!(smax.checked_next_power_of_two(), Some(smax + 1)); + assert_eq!((smax + 1).checked_next_power_of_two(), Some(smax + 1)); + assert_eq!((smax + 2).checked_next_power_of_two(), None); + assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None); + assert_eq!($T::MAX.checked_next_power_of_two(), None); + let mut next_power = 1; + for i in 1 as $T..40 { + assert_eq!(i.checked_next_power_of_two(), Some(next_power)); + if i == next_power { + next_power *= 2 + } + } + } + }; +} + +test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 } +test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 } +test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 } +test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 } +test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize } + +#[test] +fn test_pow() { + fn naive_pow<T: Mul<Output = T> + Copy>(one: T, base: T, exp: usize) -> T { + (0..exp).fold(one, |acc, _| acc * base) + } + macro_rules! assert_pow { + (($num:expr, $exp:expr) => $expected:expr) => {{ + let result = $num.pow($exp); + assert_eq!(result, $expected); + assert_eq!(result, naive_pow(1, $num, $exp)); + }}; + } + assert_pow!((3u32, 0 ) => 1); + assert_pow!((5u32, 1 ) => 5); + assert_pow!((-4i32, 2 ) => 16); + assert_pow!((8u32, 3 ) => 512); + assert_pow!((2u64, 50) => 1125899906842624); +} + +#[test] +fn test_uint_to_str_overflow() { + let mut u8_val: u8 = 255; + assert_eq!(u8_val.to_string(), "255"); + + u8_val = u8_val.wrapping_add(1); + assert_eq!(u8_val.to_string(), "0"); + + let mut u16_val: u16 = 65_535; + assert_eq!(u16_val.to_string(), "65535"); + + u16_val = u16_val.wrapping_add(1); + assert_eq!(u16_val.to_string(), "0"); + + let mut u32_val: u32 = 4_294_967_295; + assert_eq!(u32_val.to_string(), "4294967295"); + + u32_val = u32_val.wrapping_add(1); + assert_eq!(u32_val.to_string(), "0"); + + let mut u64_val: u64 = 18_446_744_073_709_551_615; + assert_eq!(u64_val.to_string(), "18446744073709551615"); + + u64_val = u64_val.wrapping_add(1); + assert_eq!(u64_val.to_string(), "0"); +} + +fn from_str<T: crate::str::FromStr>(t: &str) -> Option<T> { + crate::str::FromStr::from_str(t).ok() +} + +#[test] +fn test_uint_from_str_overflow() { + let mut u8_val: u8 = 255; + assert_eq!(from_str::<u8>("255"), Some(u8_val)); + assert_eq!(from_str::<u8>("256"), None); + + u8_val = u8_val.wrapping_add(1); + assert_eq!(from_str::<u8>("0"), Some(u8_val)); + assert_eq!(from_str::<u8>("-1"), None); + + let mut u16_val: u16 = 65_535; + assert_eq!(from_str::<u16>("65535"), Some(u16_val)); + assert_eq!(from_str::<u16>("65536"), None); + + u16_val = u16_val.wrapping_add(1); + assert_eq!(from_str::<u16>("0"), Some(u16_val)); + assert_eq!(from_str::<u16>("-1"), None); + + let mut u32_val: u32 = 4_294_967_295; + assert_eq!(from_str::<u32>("4294967295"), Some(u32_val)); + assert_eq!(from_str::<u32>("4294967296"), None); + + u32_val = u32_val.wrapping_add(1); + assert_eq!(from_str::<u32>("0"), Some(u32_val)); + assert_eq!(from_str::<u32>("-1"), None); + + let mut u64_val: u64 = 18_446_744_073_709_551_615; + assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val)); + assert_eq!(from_str::<u64>("18446744073709551616"), None); + + u64_val = u64_val.wrapping_add(1); + assert_eq!(from_str::<u64>("0"), Some(u64_val)); + assert_eq!(from_str::<u64>("-1"), None); +} diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs index 47daf0cce1b..1fe27a34600 100644 --- a/library/std/src/os/raw/mod.rs +++ b/library/std/src/os/raw/mod.rs @@ -8,6 +8,10 @@ #![stable(feature = "raw_os", since = "1.1.0")] +#[cfg(test)] +#[allow(unused_imports)] +mod tests; + #[doc(include = "char.md")] #[cfg(any( all( @@ -144,24 +148,3 @@ pub type c_double = f64; #[stable(feature = "raw_os", since = "1.1.0")] #[doc(no_inline)] pub use core::ffi::c_void; - -#[cfg(test)] -#[allow(unused_imports)] -mod tests { - use crate::any::TypeId; - use crate::mem; - - macro_rules! ok { - ($($t:ident)*) => {$( - assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(), - "{} is wrong", stringify!($t)); - )*} - } - - #[test] - fn same() { - use crate::os::raw; - ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong - c_longlong c_ulonglong c_float c_double); - } -} diff --git a/library/std/src/os/raw/tests.rs b/library/std/src/os/raw/tests.rs new file mode 100644 index 00000000000..e808faf81d6 --- /dev/null +++ b/library/std/src/os/raw/tests.rs @@ -0,0 +1,16 @@ +use crate::any::TypeId; +use crate::mem; + +macro_rules! ok { + ($($t:ident)*) => {$( + assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(), + "{} is wrong", stringify!($t)); + )*} +} + +#[test] +fn same() { + use crate::os::raw; + ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong + c_longlong c_ulonglong c_float c_double); +} diff --git a/library/std/src/path.rs b/library/std/src/path.rs index afdbdbeac3e..d71e89d0eee 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! Cross-platform path manipulation. //! //! This module provides two types, [`PathBuf`] and [`Path`] (akin to [`String`] @@ -61,6 +59,9 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(test)] +mod tests; + use crate::borrow::{Borrow, Cow}; use crate::cmp; use crate::error::Error; @@ -2741,1401 +2742,3 @@ impl Error for StripPrefixError { "prefix not found" } } - -#[cfg(test)] -mod tests { - use super::*; - - use crate::rc::Rc; - use crate::sync::Arc; - - macro_rules! t( - ($path:expr, iter: $iter:expr) => ( - { - let path = Path::new($path); - - // Forward iteration - let comps = path.iter() - .map(|p| p.to_string_lossy().into_owned()) - .collect::<Vec<String>>(); - let exp: &[&str] = &$iter; - let exps = exp.iter().map(|s| s.to_string()).collect::<Vec<String>>(); - assert!(comps == exps, "iter: Expected {:?}, found {:?}", - exps, comps); - - // Reverse iteration - let comps = Path::new($path).iter().rev() - .map(|p| p.to_string_lossy().into_owned()) - .collect::<Vec<String>>(); - let exps = exps.into_iter().rev().collect::<Vec<String>>(); - assert!(comps == exps, "iter().rev(): Expected {:?}, found {:?}", - exps, comps); - } - ); - - ($path:expr, has_root: $has_root:expr, is_absolute: $is_absolute:expr) => ( - { - let path = Path::new($path); - - let act_root = path.has_root(); - assert!(act_root == $has_root, "has_root: Expected {:?}, found {:?}", - $has_root, act_root); - - let act_abs = path.is_absolute(); - assert!(act_abs == $is_absolute, "is_absolute: Expected {:?}, found {:?}", - $is_absolute, act_abs); - } - ); - - ($path:expr, parent: $parent:expr, file_name: $file:expr) => ( - { - let path = Path::new($path); - - let parent = path.parent().map(|p| p.to_str().unwrap()); - let exp_parent: Option<&str> = $parent; - assert!(parent == exp_parent, "parent: Expected {:?}, found {:?}", - exp_parent, parent); - - let file = path.file_name().map(|p| p.to_str().unwrap()); - let exp_file: Option<&str> = $file; - assert!(file == exp_file, "file_name: Expected {:?}, found {:?}", - exp_file, file); - } - ); - - ($path:expr, file_stem: $file_stem:expr, extension: $extension:expr) => ( - { - let path = Path::new($path); - - let stem = path.file_stem().map(|p| p.to_str().unwrap()); - let exp_stem: Option<&str> = $file_stem; - assert!(stem == exp_stem, "file_stem: Expected {:?}, found {:?}", - exp_stem, stem); - - let ext = path.extension().map(|p| p.to_str().unwrap()); - let exp_ext: Option<&str> = $extension; - assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}", - exp_ext, ext); - } - ); - - ($path:expr, iter: $iter:expr, - has_root: $has_root:expr, is_absolute: $is_absolute:expr, - parent: $parent:expr, file_name: $file:expr, - file_stem: $file_stem:expr, extension: $extension:expr) => ( - { - t!($path, iter: $iter); - t!($path, has_root: $has_root, is_absolute: $is_absolute); - t!($path, parent: $parent, file_name: $file); - t!($path, file_stem: $file_stem, extension: $extension); - } - ); - ); - - #[test] - fn into() { - use crate::borrow::Cow; - - let static_path = Path::new("/home/foo"); - let static_cow_path: Cow<'static, Path> = static_path.into(); - let pathbuf = PathBuf::from("/home/foo"); - - { - let path: &Path = &pathbuf; - let borrowed_cow_path: Cow<'_, Path> = path.into(); - - assert_eq!(static_cow_path, borrowed_cow_path); - } - - let owned_cow_path: Cow<'static, Path> = pathbuf.into(); - - assert_eq!(static_cow_path, owned_cow_path); - } - - #[test] - #[cfg(unix)] - pub fn test_decompositions_unix() { - t!("", - iter: [], - has_root: false, - is_absolute: false, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("/", - iter: ["/"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("/foo", - iter: ["/", "foo"], - has_root: true, - is_absolute: true, - parent: Some("/"), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("/foo/", - iter: ["/", "foo"], - has_root: true, - is_absolute: true, - parent: Some("/"), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/bar", - iter: ["foo", "bar"], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("/foo/bar", - iter: ["/", "foo", "bar"], - has_root: true, - is_absolute: true, - parent: Some("/foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("///foo///", - iter: ["/", "foo"], - has_root: true, - is_absolute: true, - parent: Some("/"), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("///foo///bar", - iter: ["/", "foo", "bar"], - has_root: true, - is_absolute: true, - parent: Some("///foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("./.", - iter: ["."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("/..", - iter: ["/", ".."], - has_root: true, - is_absolute: true, - parent: Some("/"), - file_name: None, - file_stem: None, - extension: None - ); - - t!("../", - iter: [".."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo/.", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/..", - iter: ["foo", ".."], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo/./", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/./bar", - iter: ["foo", "bar"], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("foo/../", - iter: ["foo", ".."], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo/../bar", - iter: ["foo", "..", "bar"], - has_root: false, - is_absolute: false, - parent: Some("foo/.."), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("./a", - iter: [".", "a"], - has_root: false, - is_absolute: false, - parent: Some("."), - file_name: Some("a"), - file_stem: Some("a"), - extension: None - ); - - t!(".", - iter: ["."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("./", - iter: ["."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("a/b", - iter: ["a", "b"], - has_root: false, - is_absolute: false, - parent: Some("a"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - - t!("a//b", - iter: ["a", "b"], - has_root: false, - is_absolute: false, - parent: Some("a"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - - t!("a/./b", - iter: ["a", "b"], - has_root: false, - is_absolute: false, - parent: Some("a"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - - t!("a/b/c", - iter: ["a", "b", "c"], - has_root: false, - is_absolute: false, - parent: Some("a/b"), - file_name: Some("c"), - file_stem: Some("c"), - extension: None - ); - - t!(".foo", - iter: [".foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some(".foo"), - file_stem: Some(".foo"), - extension: None - ); - } - - #[test] - #[cfg(windows)] - pub fn test_decompositions_windows() { - t!("", - iter: [], - has_root: false, - is_absolute: false, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("/", - iter: ["\\"], - has_root: true, - is_absolute: false, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\", - iter: ["\\"], - has_root: true, - is_absolute: false, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("c:", - iter: ["c:"], - has_root: false, - is_absolute: false, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("c:\\", - iter: ["c:", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("c:/", - iter: ["c:", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("/foo", - iter: ["\\", "foo"], - has_root: true, - is_absolute: false, - parent: Some("/"), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("/foo/", - iter: ["\\", "foo"], - has_root: true, - is_absolute: false, - parent: Some("/"), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/bar", - iter: ["foo", "bar"], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("/foo/bar", - iter: ["\\", "foo", "bar"], - has_root: true, - is_absolute: false, - parent: Some("/foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("///foo///", - iter: ["\\", "foo"], - has_root: true, - is_absolute: false, - parent: Some("/"), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("///foo///bar", - iter: ["\\", "foo", "bar"], - has_root: true, - is_absolute: false, - parent: Some("///foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("./.", - iter: ["."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("/..", - iter: ["\\", ".."], - has_root: true, - is_absolute: false, - parent: Some("/"), - file_name: None, - file_stem: None, - extension: None - ); - - t!("../", - iter: [".."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo/.", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/..", - iter: ["foo", ".."], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo/./", - iter: ["foo"], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: Some("foo"), - file_stem: Some("foo"), - extension: None - ); - - t!("foo/./bar", - iter: ["foo", "bar"], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("foo/../", - iter: ["foo", ".."], - has_root: false, - is_absolute: false, - parent: Some("foo"), - file_name: None, - file_stem: None, - extension: None - ); - - t!("foo/../bar", - iter: ["foo", "..", "bar"], - has_root: false, - is_absolute: false, - parent: Some("foo/.."), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("./a", - iter: [".", "a"], - has_root: false, - is_absolute: false, - parent: Some("."), - file_name: Some("a"), - file_stem: Some("a"), - extension: None - ); - - t!(".", - iter: ["."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("./", - iter: ["."], - has_root: false, - is_absolute: false, - parent: Some(""), - file_name: None, - file_stem: None, - extension: None - ); - - t!("a/b", - iter: ["a", "b"], - has_root: false, - is_absolute: false, - parent: Some("a"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - - t!("a//b", - iter: ["a", "b"], - has_root: false, - is_absolute: false, - parent: Some("a"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - - t!("a/./b", - iter: ["a", "b"], - has_root: false, - is_absolute: false, - parent: Some("a"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - - t!("a/b/c", - iter: ["a", "b", "c"], - has_root: false, - is_absolute: false, - parent: Some("a/b"), - file_name: Some("c"), - file_stem: Some("c"), - extension: None); - - t!("a\\b\\c", - iter: ["a", "b", "c"], - has_root: false, - is_absolute: false, - parent: Some("a\\b"), - file_name: Some("c"), - file_stem: Some("c"), - extension: None - ); - - t!("\\a", - iter: ["\\", "a"], - has_root: true, - is_absolute: false, - parent: Some("\\"), - file_name: Some("a"), - file_stem: Some("a"), - extension: None - ); - - t!("c:\\foo.txt", - iter: ["c:", "\\", "foo.txt"], - has_root: true, - is_absolute: true, - parent: Some("c:\\"), - file_name: Some("foo.txt"), - file_stem: Some("foo"), - extension: Some("txt") - ); - - t!("\\\\server\\share\\foo.txt", - iter: ["\\\\server\\share", "\\", "foo.txt"], - has_root: true, - is_absolute: true, - parent: Some("\\\\server\\share\\"), - file_name: Some("foo.txt"), - file_stem: Some("foo"), - extension: Some("txt") - ); - - t!("\\\\server\\share", - iter: ["\\\\server\\share", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\server", - iter: ["\\", "server"], - has_root: true, - is_absolute: false, - parent: Some("\\"), - file_name: Some("server"), - file_stem: Some("server"), - extension: None - ); - - t!("\\\\?\\bar\\foo.txt", - iter: ["\\\\?\\bar", "\\", "foo.txt"], - has_root: true, - is_absolute: true, - parent: Some("\\\\?\\bar\\"), - file_name: Some("foo.txt"), - file_stem: Some("foo"), - extension: Some("txt") - ); - - t!("\\\\?\\bar", - iter: ["\\\\?\\bar"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\", - iter: ["\\\\?\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\UNC\\server\\share\\foo.txt", - iter: ["\\\\?\\UNC\\server\\share", "\\", "foo.txt"], - has_root: true, - is_absolute: true, - parent: Some("\\\\?\\UNC\\server\\share\\"), - file_name: Some("foo.txt"), - file_stem: Some("foo"), - extension: Some("txt") - ); - - t!("\\\\?\\UNC\\server", - iter: ["\\\\?\\UNC\\server"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\UNC\\", - iter: ["\\\\?\\UNC\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\C:\\foo.txt", - iter: ["\\\\?\\C:", "\\", "foo.txt"], - has_root: true, - is_absolute: true, - parent: Some("\\\\?\\C:\\"), - file_name: Some("foo.txt"), - file_stem: Some("foo"), - extension: Some("txt") - ); - - t!("\\\\?\\C:\\", - iter: ["\\\\?\\C:", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\C:", - iter: ["\\\\?\\C:"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\foo/bar", - iter: ["\\\\?\\foo/bar"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\C:/foo", - iter: ["\\\\?\\C:/foo"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\.\\foo\\bar", - iter: ["\\\\.\\foo", "\\", "bar"], - has_root: true, - is_absolute: true, - parent: Some("\\\\.\\foo\\"), - file_name: Some("bar"), - file_stem: Some("bar"), - extension: None - ); - - t!("\\\\.\\foo", - iter: ["\\\\.\\foo", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\.\\foo/bar", - iter: ["\\\\.\\foo/bar", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\.\\foo\\bar/baz", - iter: ["\\\\.\\foo", "\\", "bar", "baz"], - has_root: true, - is_absolute: true, - parent: Some("\\\\.\\foo\\bar"), - file_name: Some("baz"), - file_stem: Some("baz"), - extension: None - ); - - t!("\\\\.\\", - iter: ["\\\\.\\", "\\"], - has_root: true, - is_absolute: true, - parent: None, - file_name: None, - file_stem: None, - extension: None - ); - - t!("\\\\?\\a\\b\\", - iter: ["\\\\?\\a", "\\", "b"], - has_root: true, - is_absolute: true, - parent: Some("\\\\?\\a\\"), - file_name: Some("b"), - file_stem: Some("b"), - extension: None - ); - } - - #[test] - pub fn test_stem_ext() { - t!("foo", - file_stem: Some("foo"), - extension: None - ); - - t!("foo.", - file_stem: Some("foo"), - extension: Some("") - ); - - t!(".foo", - file_stem: Some(".foo"), - extension: None - ); - - t!("foo.txt", - file_stem: Some("foo"), - extension: Some("txt") - ); - - t!("foo.bar.txt", - file_stem: Some("foo.bar"), - extension: Some("txt") - ); - - t!("foo.bar.", - file_stem: Some("foo.bar"), - extension: Some("") - ); - - t!(".", file_stem: None, extension: None); - - t!("..", file_stem: None, extension: None); - - t!("", file_stem: None, extension: None); - } - - #[test] - pub fn test_push() { - macro_rules! tp( - ($path:expr, $push:expr, $expected:expr) => ( { - let mut actual = PathBuf::from($path); - actual.push($push); - assert!(actual.to_str() == Some($expected), - "pushing {:?} onto {:?}: Expected {:?}, got {:?}", - $push, $path, $expected, actual.to_str().unwrap()); - }); - ); - - if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) { - tp!("", "foo", "foo"); - tp!("foo", "bar", "foo/bar"); - tp!("foo/", "bar", "foo/bar"); - tp!("foo//", "bar", "foo//bar"); - tp!("foo/.", "bar", "foo/./bar"); - tp!("foo./.", "bar", "foo././bar"); - tp!("foo", "", "foo/"); - tp!("foo", ".", "foo/."); - tp!("foo", "..", "foo/.."); - tp!("foo", "/", "/"); - tp!("/foo/bar", "/", "/"); - tp!("/foo/bar", "/baz", "/baz"); - tp!("/foo/bar", "./baz", "/foo/bar/./baz"); - } else { - tp!("", "foo", "foo"); - tp!("foo", "bar", r"foo\bar"); - tp!("foo/", "bar", r"foo/bar"); - tp!(r"foo\", "bar", r"foo\bar"); - tp!("foo//", "bar", r"foo//bar"); - tp!(r"foo\\", "bar", r"foo\\bar"); - tp!("foo/.", "bar", r"foo/.\bar"); - tp!("foo./.", "bar", r"foo./.\bar"); - tp!(r"foo\.", "bar", r"foo\.\bar"); - tp!(r"foo.\.", "bar", r"foo.\.\bar"); - tp!("foo", "", "foo\\"); - tp!("foo", ".", r"foo\."); - tp!("foo", "..", r"foo\.."); - tp!("foo", "/", "/"); - tp!("foo", r"\", r"\"); - tp!("/foo/bar", "/", "/"); - tp!(r"\foo\bar", r"\", r"\"); - tp!("/foo/bar", "/baz", "/baz"); - tp!("/foo/bar", r"\baz", r"\baz"); - tp!("/foo/bar", "./baz", r"/foo/bar\./baz"); - tp!("/foo/bar", r".\baz", r"/foo/bar\.\baz"); - - tp!("c:\\", "windows", "c:\\windows"); - tp!("c:", "windows", "c:windows"); - - tp!("a\\b\\c", "d", "a\\b\\c\\d"); - tp!("\\a\\b\\c", "d", "\\a\\b\\c\\d"); - tp!("a\\b", "c\\d", "a\\b\\c\\d"); - tp!("a\\b", "\\c\\d", "\\c\\d"); - tp!("a\\b", ".", "a\\b\\."); - tp!("a\\b", "..\\c", "a\\b\\..\\c"); - tp!("a\\b", "C:a.txt", "C:a.txt"); - tp!("a\\b", "C:\\a.txt", "C:\\a.txt"); - tp!("C:\\a", "C:\\b.txt", "C:\\b.txt"); - tp!("C:\\a\\b\\c", "C:d", "C:d"); - tp!("C:a\\b\\c", "C:d", "C:d"); - tp!("C:", r"a\b\c", r"C:a\b\c"); - tp!("C:", r"..\a", r"C:..\a"); - tp!("\\\\server\\share\\foo", "bar", "\\\\server\\share\\foo\\bar"); - tp!("\\\\server\\share\\foo", "C:baz", "C:baz"); - tp!("\\\\?\\C:\\a\\b", "C:c\\d", "C:c\\d"); - tp!("\\\\?\\C:a\\b", "C:c\\d", "C:c\\d"); - tp!("\\\\?\\C:\\a\\b", "C:\\c\\d", "C:\\c\\d"); - tp!("\\\\?\\foo\\bar", "baz", "\\\\?\\foo\\bar\\baz"); - tp!("\\\\?\\UNC\\server\\share\\foo", "bar", "\\\\?\\UNC\\server\\share\\foo\\bar"); - tp!("\\\\?\\UNC\\server\\share", "C:\\a", "C:\\a"); - tp!("\\\\?\\UNC\\server\\share", "C:a", "C:a"); - - // Note: modified from old path API - tp!("\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\foo"); - - tp!("C:\\a", "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share"); - tp!("\\\\.\\foo\\bar", "baz", "\\\\.\\foo\\bar\\baz"); - tp!("\\\\.\\foo\\bar", "C:a", "C:a"); - // again, not sure about the following, but I'm assuming \\.\ should be verbatim - tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar"); - - tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one - } - } - - #[test] - pub fn test_pop() { - macro_rules! tp( - ($path:expr, $expected:expr, $output:expr) => ( { - let mut actual = PathBuf::from($path); - let output = actual.pop(); - assert!(actual.to_str() == Some($expected) && output == $output, - "popping from {:?}: Expected {:?}/{:?}, got {:?}/{:?}", - $path, $expected, $output, - actual.to_str().unwrap(), output); - }); - ); - - tp!("", "", false); - tp!("/", "/", false); - tp!("foo", "", true); - tp!(".", "", true); - tp!("/foo", "/", true); - tp!("/foo/bar", "/foo", true); - tp!("foo/bar", "foo", true); - tp!("foo/.", "", true); - tp!("foo//bar", "foo", true); - - if cfg!(windows) { - tp!("a\\b\\c", "a\\b", true); - tp!("\\a", "\\", true); - tp!("\\", "\\", false); - - tp!("C:\\a\\b", "C:\\a", true); - tp!("C:\\a", "C:\\", true); - tp!("C:\\", "C:\\", false); - tp!("C:a\\b", "C:a", true); - tp!("C:a", "C:", true); - tp!("C:", "C:", false); - tp!("\\\\server\\share\\a\\b", "\\\\server\\share\\a", true); - tp!("\\\\server\\share\\a", "\\\\server\\share\\", true); - tp!("\\\\server\\share", "\\\\server\\share", false); - tp!("\\\\?\\a\\b\\c", "\\\\?\\a\\b", true); - tp!("\\\\?\\a\\b", "\\\\?\\a\\", true); - tp!("\\\\?\\a", "\\\\?\\a", false); - tp!("\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true); - tp!("\\\\?\\C:\\a", "\\\\?\\C:\\", true); - tp!("\\\\?\\C:\\", "\\\\?\\C:\\", false); - tp!("\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true); - tp!("\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share\\", true); - tp!("\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false); - tp!("\\\\.\\a\\b\\c", "\\\\.\\a\\b", true); - tp!("\\\\.\\a\\b", "\\\\.\\a\\", true); - tp!("\\\\.\\a", "\\\\.\\a", false); - - tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true); - } - } - - #[test] - pub fn test_set_file_name() { - macro_rules! tfn( - ($path:expr, $file:expr, $expected:expr) => ( { - let mut p = PathBuf::from($path); - p.set_file_name($file); - assert!(p.to_str() == Some($expected), - "setting file name of {:?} to {:?}: Expected {:?}, got {:?}", - $path, $file, $expected, - p.to_str().unwrap()); - }); - ); - - tfn!("foo", "foo", "foo"); - tfn!("foo", "bar", "bar"); - tfn!("foo", "", ""); - tfn!("", "foo", "foo"); - if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) { - tfn!(".", "foo", "./foo"); - tfn!("foo/", "bar", "bar"); - tfn!("foo/.", "bar", "bar"); - tfn!("..", "foo", "../foo"); - tfn!("foo/..", "bar", "foo/../bar"); - tfn!("/", "foo", "/foo"); - } else { - tfn!(".", "foo", r".\foo"); - tfn!(r"foo\", "bar", r"bar"); - tfn!(r"foo\.", "bar", r"bar"); - tfn!("..", "foo", r"..\foo"); - tfn!(r"foo\..", "bar", r"foo\..\bar"); - tfn!(r"\", "foo", r"\foo"); - } - } - - #[test] - pub fn test_set_extension() { - macro_rules! tfe( - ($path:expr, $ext:expr, $expected:expr, $output:expr) => ( { - let mut p = PathBuf::from($path); - let output = p.set_extension($ext); - assert!(p.to_str() == Some($expected) && output == $output, - "setting extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}", - $path, $ext, $expected, $output, - p.to_str().unwrap(), output); - }); - ); - - tfe!("foo", "txt", "foo.txt", true); - tfe!("foo.bar", "txt", "foo.txt", true); - tfe!("foo.bar.baz", "txt", "foo.bar.txt", true); - tfe!(".test", "txt", ".test.txt", true); - tfe!("foo.txt", "", "foo", true); - tfe!("foo", "", "foo", true); - tfe!("", "foo", "", false); - tfe!(".", "foo", ".", false); - tfe!("foo/", "bar", "foo.bar", true); - tfe!("foo/.", "bar", "foo.bar", true); - tfe!("..", "foo", "..", false); - tfe!("foo/..", "bar", "foo/..", false); - tfe!("/", "foo", "/", false); - } - - #[test] - fn test_eq_receivers() { - use crate::borrow::Cow; - - let borrowed: &Path = Path::new("foo/bar"); - let mut owned: PathBuf = PathBuf::new(); - owned.push("foo"); - owned.push("bar"); - let borrowed_cow: Cow<'_, Path> = borrowed.into(); - let owned_cow: Cow<'_, Path> = owned.clone().into(); - - macro_rules! t { - ($($current:expr),+) => { - $( - assert_eq!($current, borrowed); - assert_eq!($current, owned); - assert_eq!($current, borrowed_cow); - assert_eq!($current, owned_cow); - )+ - } - } - - t!(borrowed, owned, borrowed_cow, owned_cow); - } - - #[test] - pub fn test_compare() { - use crate::collections::hash_map::DefaultHasher; - use crate::hash::{Hash, Hasher}; - - fn hash<T: Hash>(t: T) -> u64 { - let mut s = DefaultHasher::new(); - t.hash(&mut s); - s.finish() - } - - macro_rules! tc( - ($path1:expr, $path2:expr, eq: $eq:expr, - starts_with: $starts_with:expr, ends_with: $ends_with:expr, - relative_from: $relative_from:expr) => ({ - let path1 = Path::new($path1); - let path2 = Path::new($path2); - - let eq = path1 == path2; - assert!(eq == $eq, "{:?} == {:?}, expected {:?}, got {:?}", - $path1, $path2, $eq, eq); - assert!($eq == (hash(path1) == hash(path2)), - "{:?} == {:?}, expected {:?}, got {} and {}", - $path1, $path2, $eq, hash(path1), hash(path2)); - - let starts_with = path1.starts_with(path2); - assert!(starts_with == $starts_with, - "{:?}.starts_with({:?}), expected {:?}, got {:?}", $path1, $path2, - $starts_with, starts_with); - - let ends_with = path1.ends_with(path2); - assert!(ends_with == $ends_with, - "{:?}.ends_with({:?}), expected {:?}, got {:?}", $path1, $path2, - $ends_with, ends_with); - - let relative_from = path1.strip_prefix(path2) - .map(|p| p.to_str().unwrap()) - .ok(); - let exp: Option<&str> = $relative_from; - assert!(relative_from == exp, - "{:?}.strip_prefix({:?}), expected {:?}, got {:?}", - $path1, $path2, exp, relative_from); - }); - ); - - tc!("", "", - eq: true, - starts_with: true, - ends_with: true, - relative_from: Some("") - ); - - tc!("foo", "", - eq: false, - starts_with: true, - ends_with: true, - relative_from: Some("foo") - ); - - tc!("", "foo", - eq: false, - starts_with: false, - ends_with: false, - relative_from: None - ); - - tc!("foo", "foo", - eq: true, - starts_with: true, - ends_with: true, - relative_from: Some("") - ); - - tc!("foo/", "foo", - eq: true, - starts_with: true, - ends_with: true, - relative_from: Some("") - ); - - tc!("foo/bar", "foo", - eq: false, - starts_with: true, - ends_with: false, - relative_from: Some("bar") - ); - - tc!("foo/bar/baz", "foo/bar", - eq: false, - starts_with: true, - ends_with: false, - relative_from: Some("baz") - ); - - tc!("foo/bar", "foo/bar/baz", - eq: false, - starts_with: false, - ends_with: false, - relative_from: None - ); - - tc!("./foo/bar/", ".", - eq: false, - starts_with: true, - ends_with: false, - relative_from: Some("foo/bar") - ); - - if cfg!(windows) { - tc!(r"C:\src\rust\cargo-test\test\Cargo.toml", - r"c:\src\rust\cargo-test\test", - eq: false, - starts_with: true, - ends_with: false, - relative_from: Some("Cargo.toml") - ); - - tc!(r"c:\foo", r"C:\foo", - eq: true, - starts_with: true, - ends_with: true, - relative_from: Some("") - ); - } - } - - #[test] - fn test_components_debug() { - let path = Path::new("/tmp"); - - let mut components = path.components(); - - let expected = "Components([RootDir, Normal(\"tmp\")])"; - let actual = format!("{:?}", components); - assert_eq!(expected, actual); - - let _ = components.next().unwrap(); - let expected = "Components([Normal(\"tmp\")])"; - let actual = format!("{:?}", components); - assert_eq!(expected, actual); - - let _ = components.next().unwrap(); - let expected = "Components([])"; - let actual = format!("{:?}", components); - assert_eq!(expected, actual); - } - - #[cfg(unix)] - #[test] - fn test_iter_debug() { - let path = Path::new("/tmp"); - - let mut iter = path.iter(); - - let expected = "Iter([\"/\", \"tmp\"])"; - let actual = format!("{:?}", iter); - assert_eq!(expected, actual); - - let _ = iter.next().unwrap(); - let expected = "Iter([\"tmp\"])"; - let actual = format!("{:?}", iter); - assert_eq!(expected, actual); - - let _ = iter.next().unwrap(); - let expected = "Iter([])"; - let actual = format!("{:?}", iter); - assert_eq!(expected, actual); - } - - #[test] - fn into_boxed() { - let orig: &str = "some/sort/of/path"; - let path = Path::new(orig); - let boxed: Box<Path> = Box::from(path); - let path_buf = path.to_owned().into_boxed_path().into_path_buf(); - assert_eq!(path, &*boxed); - assert_eq!(&*boxed, &*path_buf); - assert_eq!(&*path_buf, path); - } - - #[test] - fn test_clone_into() { - let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious"); - let path = Path::new("short"); - path.clone_into(&mut path_buf); - assert_eq!(path, path_buf); - assert!(path_buf.into_os_string().capacity() >= 15); - } - - #[test] - fn display_format_flags() { - assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b"); - assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b"); - } - - #[test] - fn into_rc() { - let orig = "hello/world"; - let path = Path::new(orig); - let rc: Rc<Path> = Rc::from(path); - let arc: Arc<Path> = Arc::from(path); - - assert_eq!(&*rc, path); - assert_eq!(&*arc, path); - - let rc2: Rc<Path> = Rc::from(path.to_owned()); - let arc2: Arc<Path> = Arc::from(path.to_owned()); - - assert_eq!(&*rc2, path); - assert_eq!(&*arc2, path); - } -} diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs new file mode 100644 index 00000000000..ff94fda5a22 --- /dev/null +++ b/library/std/src/path/tests.rs @@ -0,0 +1,1394 @@ +use super::*; + +use crate::rc::Rc; +use crate::sync::Arc; + +macro_rules! t( + ($path:expr, iter: $iter:expr) => ( + { + let path = Path::new($path); + + // Forward iteration + let comps = path.iter() + .map(|p| p.to_string_lossy().into_owned()) + .collect::<Vec<String>>(); + let exp: &[&str] = &$iter; + let exps = exp.iter().map(|s| s.to_string()).collect::<Vec<String>>(); + assert!(comps == exps, "iter: Expected {:?}, found {:?}", + exps, comps); + + // Reverse iteration + let comps = Path::new($path).iter().rev() + .map(|p| p.to_string_lossy().into_owned()) + .collect::<Vec<String>>(); + let exps = exps.into_iter().rev().collect::<Vec<String>>(); + assert!(comps == exps, "iter().rev(): Expected {:?}, found {:?}", + exps, comps); + } + ); + + ($path:expr, has_root: $has_root:expr, is_absolute: $is_absolute:expr) => ( + { + let path = Path::new($path); + + let act_root = path.has_root(); + assert!(act_root == $has_root, "has_root: Expected {:?}, found {:?}", + $has_root, act_root); + + let act_abs = path.is_absolute(); + assert!(act_abs == $is_absolute, "is_absolute: Expected {:?}, found {:?}", + $is_absolute, act_abs); + } + ); + + ($path:expr, parent: $parent:expr, file_name: $file:expr) => ( + { + let path = Path::new($path); + + let parent = path.parent().map(|p| p.to_str().unwrap()); + let exp_parent: Option<&str> = $parent; + assert!(parent == exp_parent, "parent: Expected {:?}, found {:?}", + exp_parent, parent); + + let file = path.file_name().map(|p| p.to_str().unwrap()); + let exp_file: Option<&str> = $file; + assert!(file == exp_file, "file_name: Expected {:?}, found {:?}", + exp_file, file); + } + ); + + ($path:expr, file_stem: $file_stem:expr, extension: $extension:expr) => ( + { + let path = Path::new($path); + + let stem = path.file_stem().map(|p| p.to_str().unwrap()); + let exp_stem: Option<&str> = $file_stem; + assert!(stem == exp_stem, "file_stem: Expected {:?}, found {:?}", + exp_stem, stem); + + let ext = path.extension().map(|p| p.to_str().unwrap()); + let exp_ext: Option<&str> = $extension; + assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}", + exp_ext, ext); + } + ); + + ($path:expr, iter: $iter:expr, + has_root: $has_root:expr, is_absolute: $is_absolute:expr, + parent: $parent:expr, file_name: $file:expr, + file_stem: $file_stem:expr, extension: $extension:expr) => ( + { + t!($path, iter: $iter); + t!($path, has_root: $has_root, is_absolute: $is_absolute); + t!($path, parent: $parent, file_name: $file); + t!($path, file_stem: $file_stem, extension: $extension); + } + ); +); + +#[test] +fn into() { + use crate::borrow::Cow; + + let static_path = Path::new("/home/foo"); + let static_cow_path: Cow<'static, Path> = static_path.into(); + let pathbuf = PathBuf::from("/home/foo"); + + { + let path: &Path = &pathbuf; + let borrowed_cow_path: Cow<'_, Path> = path.into(); + + assert_eq!(static_cow_path, borrowed_cow_path); + } + + let owned_cow_path: Cow<'static, Path> = pathbuf.into(); + + assert_eq!(static_cow_path, owned_cow_path); +} + +#[test] +#[cfg(unix)] +pub fn test_decompositions_unix() { + t!("", + iter: [], + has_root: false, + is_absolute: false, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("/", + iter: ["/"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("/foo", + iter: ["/", "foo"], + has_root: true, + is_absolute: true, + parent: Some("/"), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("/foo/", + iter: ["/", "foo"], + has_root: true, + is_absolute: true, + parent: Some("/"), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/bar", + iter: ["foo", "bar"], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("/foo/bar", + iter: ["/", "foo", "bar"], + has_root: true, + is_absolute: true, + parent: Some("/foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("///foo///", + iter: ["/", "foo"], + has_root: true, + is_absolute: true, + parent: Some("/"), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("///foo///bar", + iter: ["/", "foo", "bar"], + has_root: true, + is_absolute: true, + parent: Some("///foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("./.", + iter: ["."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("/..", + iter: ["/", ".."], + has_root: true, + is_absolute: true, + parent: Some("/"), + file_name: None, + file_stem: None, + extension: None + ); + + t!("../", + iter: [".."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo/.", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/..", + iter: ["foo", ".."], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo/./", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/./bar", + iter: ["foo", "bar"], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("foo/../", + iter: ["foo", ".."], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo/../bar", + iter: ["foo", "..", "bar"], + has_root: false, + is_absolute: false, + parent: Some("foo/.."), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("./a", + iter: [".", "a"], + has_root: false, + is_absolute: false, + parent: Some("."), + file_name: Some("a"), + file_stem: Some("a"), + extension: None + ); + + t!(".", + iter: ["."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("./", + iter: ["."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("a/b", + iter: ["a", "b"], + has_root: false, + is_absolute: false, + parent: Some("a"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); + + t!("a//b", + iter: ["a", "b"], + has_root: false, + is_absolute: false, + parent: Some("a"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); + + t!("a/./b", + iter: ["a", "b"], + has_root: false, + is_absolute: false, + parent: Some("a"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); + + t!("a/b/c", + iter: ["a", "b", "c"], + has_root: false, + is_absolute: false, + parent: Some("a/b"), + file_name: Some("c"), + file_stem: Some("c"), + extension: None + ); + + t!(".foo", + iter: [".foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some(".foo"), + file_stem: Some(".foo"), + extension: None + ); +} + +#[test] +#[cfg(windows)] +pub fn test_decompositions_windows() { + t!("", + iter: [], + has_root: false, + is_absolute: false, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("/", + iter: ["\\"], + has_root: true, + is_absolute: false, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\", + iter: ["\\"], + has_root: true, + is_absolute: false, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("c:", + iter: ["c:"], + has_root: false, + is_absolute: false, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("c:\\", + iter: ["c:", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("c:/", + iter: ["c:", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("/foo", + iter: ["\\", "foo"], + has_root: true, + is_absolute: false, + parent: Some("/"), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("/foo/", + iter: ["\\", "foo"], + has_root: true, + is_absolute: false, + parent: Some("/"), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/bar", + iter: ["foo", "bar"], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("/foo/bar", + iter: ["\\", "foo", "bar"], + has_root: true, + is_absolute: false, + parent: Some("/foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("///foo///", + iter: ["\\", "foo"], + has_root: true, + is_absolute: false, + parent: Some("/"), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("///foo///bar", + iter: ["\\", "foo", "bar"], + has_root: true, + is_absolute: false, + parent: Some("///foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("./.", + iter: ["."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("/..", + iter: ["\\", ".."], + has_root: true, + is_absolute: false, + parent: Some("/"), + file_name: None, + file_stem: None, + extension: None + ); + + t!("../", + iter: [".."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo/.", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/..", + iter: ["foo", ".."], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo/./", + iter: ["foo"], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: Some("foo"), + file_stem: Some("foo"), + extension: None + ); + + t!("foo/./bar", + iter: ["foo", "bar"], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("foo/../", + iter: ["foo", ".."], + has_root: false, + is_absolute: false, + parent: Some("foo"), + file_name: None, + file_stem: None, + extension: None + ); + + t!("foo/../bar", + iter: ["foo", "..", "bar"], + has_root: false, + is_absolute: false, + parent: Some("foo/.."), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("./a", + iter: [".", "a"], + has_root: false, + is_absolute: false, + parent: Some("."), + file_name: Some("a"), + file_stem: Some("a"), + extension: None + ); + + t!(".", + iter: ["."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("./", + iter: ["."], + has_root: false, + is_absolute: false, + parent: Some(""), + file_name: None, + file_stem: None, + extension: None + ); + + t!("a/b", + iter: ["a", "b"], + has_root: false, + is_absolute: false, + parent: Some("a"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); + + t!("a//b", + iter: ["a", "b"], + has_root: false, + is_absolute: false, + parent: Some("a"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); + + t!("a/./b", + iter: ["a", "b"], + has_root: false, + is_absolute: false, + parent: Some("a"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); + + t!("a/b/c", + iter: ["a", "b", "c"], + has_root: false, + is_absolute: false, + parent: Some("a/b"), + file_name: Some("c"), + file_stem: Some("c"), + extension: None); + + t!("a\\b\\c", + iter: ["a", "b", "c"], + has_root: false, + is_absolute: false, + parent: Some("a\\b"), + file_name: Some("c"), + file_stem: Some("c"), + extension: None + ); + + t!("\\a", + iter: ["\\", "a"], + has_root: true, + is_absolute: false, + parent: Some("\\"), + file_name: Some("a"), + file_stem: Some("a"), + extension: None + ); + + t!("c:\\foo.txt", + iter: ["c:", "\\", "foo.txt"], + has_root: true, + is_absolute: true, + parent: Some("c:\\"), + file_name: Some("foo.txt"), + file_stem: Some("foo"), + extension: Some("txt") + ); + + t!("\\\\server\\share\\foo.txt", + iter: ["\\\\server\\share", "\\", "foo.txt"], + has_root: true, + is_absolute: true, + parent: Some("\\\\server\\share\\"), + file_name: Some("foo.txt"), + file_stem: Some("foo"), + extension: Some("txt") + ); + + t!("\\\\server\\share", + iter: ["\\\\server\\share", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\server", + iter: ["\\", "server"], + has_root: true, + is_absolute: false, + parent: Some("\\"), + file_name: Some("server"), + file_stem: Some("server"), + extension: None + ); + + t!("\\\\?\\bar\\foo.txt", + iter: ["\\\\?\\bar", "\\", "foo.txt"], + has_root: true, + is_absolute: true, + parent: Some("\\\\?\\bar\\"), + file_name: Some("foo.txt"), + file_stem: Some("foo"), + extension: Some("txt") + ); + + t!("\\\\?\\bar", + iter: ["\\\\?\\bar"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\", + iter: ["\\\\?\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\UNC\\server\\share\\foo.txt", + iter: ["\\\\?\\UNC\\server\\share", "\\", "foo.txt"], + has_root: true, + is_absolute: true, + parent: Some("\\\\?\\UNC\\server\\share\\"), + file_name: Some("foo.txt"), + file_stem: Some("foo"), + extension: Some("txt") + ); + + t!("\\\\?\\UNC\\server", + iter: ["\\\\?\\UNC\\server"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\UNC\\", + iter: ["\\\\?\\UNC\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\C:\\foo.txt", + iter: ["\\\\?\\C:", "\\", "foo.txt"], + has_root: true, + is_absolute: true, + parent: Some("\\\\?\\C:\\"), + file_name: Some("foo.txt"), + file_stem: Some("foo"), + extension: Some("txt") + ); + + t!("\\\\?\\C:\\", + iter: ["\\\\?\\C:", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\C:", + iter: ["\\\\?\\C:"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\foo/bar", + iter: ["\\\\?\\foo/bar"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\C:/foo", + iter: ["\\\\?\\C:/foo"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\.\\foo\\bar", + iter: ["\\\\.\\foo", "\\", "bar"], + has_root: true, + is_absolute: true, + parent: Some("\\\\.\\foo\\"), + file_name: Some("bar"), + file_stem: Some("bar"), + extension: None + ); + + t!("\\\\.\\foo", + iter: ["\\\\.\\foo", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\.\\foo/bar", + iter: ["\\\\.\\foo/bar", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\.\\foo\\bar/baz", + iter: ["\\\\.\\foo", "\\", "bar", "baz"], + has_root: true, + is_absolute: true, + parent: Some("\\\\.\\foo\\bar"), + file_name: Some("baz"), + file_stem: Some("baz"), + extension: None + ); + + t!("\\\\.\\", + iter: ["\\\\.\\", "\\"], + has_root: true, + is_absolute: true, + parent: None, + file_name: None, + file_stem: None, + extension: None + ); + + t!("\\\\?\\a\\b\\", + iter: ["\\\\?\\a", "\\", "b"], + has_root: true, + is_absolute: true, + parent: Some("\\\\?\\a\\"), + file_name: Some("b"), + file_stem: Some("b"), + extension: None + ); +} + +#[test] +pub fn test_stem_ext() { + t!("foo", + file_stem: Some("foo"), + extension: None + ); + + t!("foo.", + file_stem: Some("foo"), + extension: Some("") + ); + + t!(".foo", + file_stem: Some(".foo"), + extension: None + ); + + t!("foo.txt", + file_stem: Some("foo"), + extension: Some("txt") + ); + + t!("foo.bar.txt", + file_stem: Some("foo.bar"), + extension: Some("txt") + ); + + t!("foo.bar.", + file_stem: Some("foo.bar"), + extension: Some("") + ); + + t!(".", file_stem: None, extension: None); + + t!("..", file_stem: None, extension: None); + + t!("", file_stem: None, extension: None); +} + +#[test] +pub fn test_push() { + macro_rules! tp( + ($path:expr, $push:expr, $expected:expr) => ( { + let mut actual = PathBuf::from($path); + actual.push($push); + assert!(actual.to_str() == Some($expected), + "pushing {:?} onto {:?}: Expected {:?}, got {:?}", + $push, $path, $expected, actual.to_str().unwrap()); + }); + ); + + if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) { + tp!("", "foo", "foo"); + tp!("foo", "bar", "foo/bar"); + tp!("foo/", "bar", "foo/bar"); + tp!("foo//", "bar", "foo//bar"); + tp!("foo/.", "bar", "foo/./bar"); + tp!("foo./.", "bar", "foo././bar"); + tp!("foo", "", "foo/"); + tp!("foo", ".", "foo/."); + tp!("foo", "..", "foo/.."); + tp!("foo", "/", "/"); + tp!("/foo/bar", "/", "/"); + tp!("/foo/bar", "/baz", "/baz"); + tp!("/foo/bar", "./baz", "/foo/bar/./baz"); + } else { + tp!("", "foo", "foo"); + tp!("foo", "bar", r"foo\bar"); + tp!("foo/", "bar", r"foo/bar"); + tp!(r"foo\", "bar", r"foo\bar"); + tp!("foo//", "bar", r"foo//bar"); + tp!(r"foo\\", "bar", r"foo\\bar"); + tp!("foo/.", "bar", r"foo/.\bar"); + tp!("foo./.", "bar", r"foo./.\bar"); + tp!(r"foo\.", "bar", r"foo\.\bar"); + tp!(r"foo.\.", "bar", r"foo.\.\bar"); + tp!("foo", "", "foo\\"); + tp!("foo", ".", r"foo\."); + tp!("foo", "..", r"foo\.."); + tp!("foo", "/", "/"); + tp!("foo", r"\", r"\"); + tp!("/foo/bar", "/", "/"); + tp!(r"\foo\bar", r"\", r"\"); + tp!("/foo/bar", "/baz", "/baz"); + tp!("/foo/bar", r"\baz", r"\baz"); + tp!("/foo/bar", "./baz", r"/foo/bar\./baz"); + tp!("/foo/bar", r".\baz", r"/foo/bar\.\baz"); + + tp!("c:\\", "windows", "c:\\windows"); + tp!("c:", "windows", "c:windows"); + + tp!("a\\b\\c", "d", "a\\b\\c\\d"); + tp!("\\a\\b\\c", "d", "\\a\\b\\c\\d"); + tp!("a\\b", "c\\d", "a\\b\\c\\d"); + tp!("a\\b", "\\c\\d", "\\c\\d"); + tp!("a\\b", ".", "a\\b\\."); + tp!("a\\b", "..\\c", "a\\b\\..\\c"); + tp!("a\\b", "C:a.txt", "C:a.txt"); + tp!("a\\b", "C:\\a.txt", "C:\\a.txt"); + tp!("C:\\a", "C:\\b.txt", "C:\\b.txt"); + tp!("C:\\a\\b\\c", "C:d", "C:d"); + tp!("C:a\\b\\c", "C:d", "C:d"); + tp!("C:", r"a\b\c", r"C:a\b\c"); + tp!("C:", r"..\a", r"C:..\a"); + tp!("\\\\server\\share\\foo", "bar", "\\\\server\\share\\foo\\bar"); + tp!("\\\\server\\share\\foo", "C:baz", "C:baz"); + tp!("\\\\?\\C:\\a\\b", "C:c\\d", "C:c\\d"); + tp!("\\\\?\\C:a\\b", "C:c\\d", "C:c\\d"); + tp!("\\\\?\\C:\\a\\b", "C:\\c\\d", "C:\\c\\d"); + tp!("\\\\?\\foo\\bar", "baz", "\\\\?\\foo\\bar\\baz"); + tp!("\\\\?\\UNC\\server\\share\\foo", "bar", "\\\\?\\UNC\\server\\share\\foo\\bar"); + tp!("\\\\?\\UNC\\server\\share", "C:\\a", "C:\\a"); + tp!("\\\\?\\UNC\\server\\share", "C:a", "C:a"); + + // Note: modified from old path API + tp!("\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\foo"); + + tp!("C:\\a", "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share"); + tp!("\\\\.\\foo\\bar", "baz", "\\\\.\\foo\\bar\\baz"); + tp!("\\\\.\\foo\\bar", "C:a", "C:a"); + // again, not sure about the following, but I'm assuming \\.\ should be verbatim + tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar"); + + tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one + } +} + +#[test] +pub fn test_pop() { + macro_rules! tp( + ($path:expr, $expected:expr, $output:expr) => ( { + let mut actual = PathBuf::from($path); + let output = actual.pop(); + assert!(actual.to_str() == Some($expected) && output == $output, + "popping from {:?}: Expected {:?}/{:?}, got {:?}/{:?}", + $path, $expected, $output, + actual.to_str().unwrap(), output); + }); + ); + + tp!("", "", false); + tp!("/", "/", false); + tp!("foo", "", true); + tp!(".", "", true); + tp!("/foo", "/", true); + tp!("/foo/bar", "/foo", true); + tp!("foo/bar", "foo", true); + tp!("foo/.", "", true); + tp!("foo//bar", "foo", true); + + if cfg!(windows) { + tp!("a\\b\\c", "a\\b", true); + tp!("\\a", "\\", true); + tp!("\\", "\\", false); + + tp!("C:\\a\\b", "C:\\a", true); + tp!("C:\\a", "C:\\", true); + tp!("C:\\", "C:\\", false); + tp!("C:a\\b", "C:a", true); + tp!("C:a", "C:", true); + tp!("C:", "C:", false); + tp!("\\\\server\\share\\a\\b", "\\\\server\\share\\a", true); + tp!("\\\\server\\share\\a", "\\\\server\\share\\", true); + tp!("\\\\server\\share", "\\\\server\\share", false); + tp!("\\\\?\\a\\b\\c", "\\\\?\\a\\b", true); + tp!("\\\\?\\a\\b", "\\\\?\\a\\", true); + tp!("\\\\?\\a", "\\\\?\\a", false); + tp!("\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true); + tp!("\\\\?\\C:\\a", "\\\\?\\C:\\", true); + tp!("\\\\?\\C:\\", "\\\\?\\C:\\", false); + tp!("\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true); + tp!("\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share\\", true); + tp!("\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false); + tp!("\\\\.\\a\\b\\c", "\\\\.\\a\\b", true); + tp!("\\\\.\\a\\b", "\\\\.\\a\\", true); + tp!("\\\\.\\a", "\\\\.\\a", false); + + tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true); + } +} + +#[test] +pub fn test_set_file_name() { + macro_rules! tfn( + ($path:expr, $file:expr, $expected:expr) => ( { + let mut p = PathBuf::from($path); + p.set_file_name($file); + assert!(p.to_str() == Some($expected), + "setting file name of {:?} to {:?}: Expected {:?}, got {:?}", + $path, $file, $expected, + p.to_str().unwrap()); + }); + ); + + tfn!("foo", "foo", "foo"); + tfn!("foo", "bar", "bar"); + tfn!("foo", "", ""); + tfn!("", "foo", "foo"); + if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) { + tfn!(".", "foo", "./foo"); + tfn!("foo/", "bar", "bar"); + tfn!("foo/.", "bar", "bar"); + tfn!("..", "foo", "../foo"); + tfn!("foo/..", "bar", "foo/../bar"); + tfn!("/", "foo", "/foo"); + } else { + tfn!(".", "foo", r".\foo"); + tfn!(r"foo\", "bar", r"bar"); + tfn!(r"foo\.", "bar", r"bar"); + tfn!("..", "foo", r"..\foo"); + tfn!(r"foo\..", "bar", r"foo\..\bar"); + tfn!(r"\", "foo", r"\foo"); + } +} + +#[test] +pub fn test_set_extension() { + macro_rules! tfe( + ($path:expr, $ext:expr, $expected:expr, $output:expr) => ( { + let mut p = PathBuf::from($path); + let output = p.set_extension($ext); + assert!(p.to_str() == Some($expected) && output == $output, + "setting extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}", + $path, $ext, $expected, $output, + p.to_str().unwrap(), output); + }); + ); + + tfe!("foo", "txt", "foo.txt", true); + tfe!("foo.bar", "txt", "foo.txt", true); + tfe!("foo.bar.baz", "txt", "foo.bar.txt", true); + tfe!(".test", "txt", ".test.txt", true); + tfe!("foo.txt", "", "foo", true); + tfe!("foo", "", "foo", true); + tfe!("", "foo", "", false); + tfe!(".", "foo", ".", false); + tfe!("foo/", "bar", "foo.bar", true); + tfe!("foo/.", "bar", "foo.bar", true); + tfe!("..", "foo", "..", false); + tfe!("foo/..", "bar", "foo/..", false); + tfe!("/", "foo", "/", false); +} + +#[test] +fn test_eq_receivers() { + use crate::borrow::Cow; + + let borrowed: &Path = Path::new("foo/bar"); + let mut owned: PathBuf = PathBuf::new(); + owned.push("foo"); + owned.push("bar"); + let borrowed_cow: Cow<'_, Path> = borrowed.into(); + let owned_cow: Cow<'_, Path> = owned.clone().into(); + + macro_rules! t { + ($($current:expr),+) => { + $( + assert_eq!($current, borrowed); + assert_eq!($current, owned); + assert_eq!($current, borrowed_cow); + assert_eq!($current, owned_cow); + )+ + } + } + + t!(borrowed, owned, borrowed_cow, owned_cow); +} + +#[test] +pub fn test_compare() { + use crate::collections::hash_map::DefaultHasher; + use crate::hash::{Hash, Hasher}; + + fn hash<T: Hash>(t: T) -> u64 { + let mut s = DefaultHasher::new(); + t.hash(&mut s); + s.finish() + } + + macro_rules! tc( + ($path1:expr, $path2:expr, eq: $eq:expr, + starts_with: $starts_with:expr, ends_with: $ends_with:expr, + relative_from: $relative_from:expr) => ({ + let path1 = Path::new($path1); + let path2 = Path::new($path2); + + let eq = path1 == path2; + assert!(eq == $eq, "{:?} == {:?}, expected {:?}, got {:?}", + $path1, $path2, $eq, eq); + assert!($eq == (hash(path1) == hash(path2)), + "{:?} == {:?}, expected {:?}, got {} and {}", + $path1, $path2, $eq, hash(path1), hash(path2)); + + let starts_with = path1.starts_with(path2); + assert!(starts_with == $starts_with, + "{:?}.starts_with({:?}), expected {:?}, got {:?}", $path1, $path2, + $starts_with, starts_with); + + let ends_with = path1.ends_with(path2); + assert!(ends_with == $ends_with, + "{:?}.ends_with({:?}), expected {:?}, got {:?}", $path1, $path2, + $ends_with, ends_with); + + let relative_from = path1.strip_prefix(path2) + .map(|p| p.to_str().unwrap()) + .ok(); + let exp: Option<&str> = $relative_from; + assert!(relative_from == exp, + "{:?}.strip_prefix({:?}), expected {:?}, got {:?}", + $path1, $path2, exp, relative_from); + }); + ); + + tc!("", "", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo", "", + eq: false, + starts_with: true, + ends_with: true, + relative_from: Some("foo") + ); + + tc!("", "foo", + eq: false, + starts_with: false, + ends_with: false, + relative_from: None + ); + + tc!("foo", "foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo/", "foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo/bar", "foo", + eq: false, + starts_with: true, + ends_with: false, + relative_from: Some("bar") + ); + + tc!("foo/bar/baz", "foo/bar", + eq: false, + starts_with: true, + ends_with: false, + relative_from: Some("baz") + ); + + tc!("foo/bar", "foo/bar/baz", + eq: false, + starts_with: false, + ends_with: false, + relative_from: None + ); + + tc!("./foo/bar/", ".", + eq: false, + starts_with: true, + ends_with: false, + relative_from: Some("foo/bar") + ); + + if cfg!(windows) { + tc!(r"C:\src\rust\cargo-test\test\Cargo.toml", + r"c:\src\rust\cargo-test\test", + eq: false, + starts_with: true, + ends_with: false, + relative_from: Some("Cargo.toml") + ); + + tc!(r"c:\foo", r"C:\foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + } +} + +#[test] +fn test_components_debug() { + let path = Path::new("/tmp"); + + let mut components = path.components(); + + let expected = "Components([RootDir, Normal(\"tmp\")])"; + let actual = format!("{:?}", components); + assert_eq!(expected, actual); + + let _ = components.next().unwrap(); + let expected = "Components([Normal(\"tmp\")])"; + let actual = format!("{:?}", components); + assert_eq!(expected, actual); + + let _ = components.next().unwrap(); + let expected = "Components([])"; + let actual = format!("{:?}", components); + assert_eq!(expected, actual); +} + +#[cfg(unix)] +#[test] +fn test_iter_debug() { + let path = Path::new("/tmp"); + + let mut iter = path.iter(); + + let expected = "Iter([\"/\", \"tmp\"])"; + let actual = format!("{:?}", iter); + assert_eq!(expected, actual); + + let _ = iter.next().unwrap(); + let expected = "Iter([\"tmp\"])"; + let actual = format!("{:?}", iter); + assert_eq!(expected, actual); + + let _ = iter.next().unwrap(); + let expected = "Iter([])"; + let actual = format!("{:?}", iter); + assert_eq!(expected, actual); +} + +#[test] +fn into_boxed() { + let orig: &str = "some/sort/of/path"; + let path = Path::new(orig); + let boxed: Box<Path> = Box::from(path); + let path_buf = path.to_owned().into_boxed_path().into_path_buf(); + assert_eq!(path, &*boxed); + assert_eq!(&*boxed, &*path_buf); + assert_eq!(&*path_buf, path); +} + +#[test] +fn test_clone_into() { + let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious"); + let path = Path::new("short"); + path.clone_into(&mut path_buf); + assert_eq!(path, path_buf); + assert!(path_buf.into_os_string().capacity() >= 15); +} + +#[test] +fn display_format_flags() { + assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b"); + assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b"); +} + +#[test] +fn into_rc() { + let orig = "hello/world"; + let path = Path::new(orig); + let rc: Rc<Path> = Rc::from(path); + let arc: Arc<Path> = Arc::from(path); + + assert_eq!(&*rc, path); + assert_eq!(&*arc, path); + + let rc2: Rc<Path> = Rc::from(path.to_owned()); + let arc2: Arc<Path> = Arc::from(path.to_owned()); + + assert_eq!(&*rc2, path); + assert_eq!(&*arc2, path); +} diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index 710c616be73..c7a7c779d3c 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -75,7 +75,7 @@ //! [`std::result`]: crate::result //! [`std::slice`]: crate::slice //! [`std::string`]: crate::string -//! [`std::vec`]: ../vec/index.html +//! [`std::vec`]: mod@crate::vec //! [`to_owned`]: crate::borrow::ToOwned::to_owned //! [book-closures]: ../../book/ch13-01-closures.html //! [book-dtor]: ../../book/ch15-03-drop.html diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 2339ca527bd..2a4cb22cc52 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -1,7 +1,6 @@ #[doc(primitive = "bool")] #[doc(alias = "true")] #[doc(alias = "false")] -// /// The boolean type. /// /// The `bool` represents a value, which could only be either `true` or `false`. If you cast @@ -12,8 +11,8 @@ /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., /// which allow us to perform boolean operations using `&`, `|` and `!`. /// -/// `if` always demands a `bool` value. [`assert!`], being an important macro in testing, -/// checks whether an expression returns `true`. +/// `if` always demands a `bool` value. [`assert!`], which is an important macro in testing, +/// checks whether an expression returns `true` and panics if it isn't. /// /// ``` /// let bool_val = true & false | false; @@ -194,14 +193,48 @@ mod prim_bool {} /// # `!` and traits /// /// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl` -/// which doesn't `panic!`. As it turns out, most traits can have an `impl` for `!`. Take [`Debug`] +/// which doesn't `panic!`. The reason is that functions returning an `impl Trait` where `!` +/// does not have an `impl` of `Trait` cannot diverge as their only possible code path. In other +/// words, they can't return `!` from every code path. As an example, this code doesn't compile: +/// +/// ```compile_fail +/// use core::ops::Add; +/// +/// fn foo() -> impl Add<u32> { +/// unimplemented!() +/// } +/// ``` +/// +/// But this code does: +/// +/// ``` +/// use core::ops::Add; +/// +/// fn foo() -> impl Add<u32> { +/// if true { +/// unimplemented!() +/// } else { +/// 0 +/// } +/// } +/// ``` +/// +/// The reason is that, in the first example, there are many possible types that `!` could coerce +/// to, because many types implement `Add<u32>`. However, in the second example, +/// the `else` branch returns a `0`, which the compiler infers from the return type to be of type +/// `u32`. Since `u32` is a concrete type, `!` can and will be coerced to it. See issue [#36375] +/// for more information on this quirk of `!`. +/// +/// [#36375]: https://github.com/rust-lang/rust/issues/36375 +/// +/// As it turns out, though, most traits can have an `impl` for `!`. Take [`Debug`] /// for example: /// /// ``` /// #![feature(never_type)] /// # use std::fmt; /// # trait Debug { -/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result; +/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result; /// # } /// impl Debug for ! { /// fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -477,7 +510,7 @@ mod prim_pointer {} /// an array. Indeed, this provides most of the API for working with arrays. /// Slices have a dynamic size and do not coerce to arrays. /// -/// You can move elements out of an array with a slice pattern. If you want +/// You can move elements out of an array with a [slice pattern]. If you want /// one element, see [`mem::replace`]. /// /// # Examples @@ -519,7 +552,7 @@ mod prim_pointer {} /// for x in &array { } /// ``` /// -/// You can use a slice pattern to move elements out of an array: +/// You can use a [slice pattern] to move elements out of an array: /// /// ``` /// fn move_away(_: String) { /* Do interesting things. */ } @@ -534,7 +567,7 @@ mod prim_pointer {} /// [`Hash`]: hash::Hash /// [`Borrow`]: borrow::Borrow /// [`BorrowMut`]: borrow::BorrowMut -/// +/// [slice pattern]: ../reference/patterns.html#slice-patterns #[stable(feature = "rust1", since = "1.0.0")] mod prim_array {} diff --git a/library/std/src/process.rs b/library/std/src/process.rs index c42bc109652..d1960a049d9 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -96,6 +96,9 @@ #![stable(feature = "process", since = "1.0.0")] +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] +mod tests; + use crate::io::prelude::*; use crate::ffi::OsStr; @@ -1702,411 +1705,3 @@ impl Termination for ExitCode { self.0.as_i32() } } - -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] -mod tests { - use crate::io::prelude::*; - - use super::{Command, Output, Stdio}; - use crate::io::ErrorKind; - use crate::str; - - // FIXME(#10380) these tests should not all be ignored on android. - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn smoke() { - let p = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "exit 0"]).spawn() - } else { - Command::new("true").spawn() - }; - assert!(p.is_ok()); - let mut p = p.unwrap(); - assert!(p.wait().unwrap().success()); - } - - #[test] - #[cfg_attr(target_os = "android", ignore)] - fn smoke_failure() { - match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() { - Ok(..) => panic!(), - Err(..) => {} - } - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn exit_reported_right() { - let p = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "exit 1"]).spawn() - } else { - Command::new("false").spawn() - }; - assert!(p.is_ok()); - let mut p = p.unwrap(); - assert!(p.wait().unwrap().code() == Some(1)); - drop(p.wait()); - } - - #[test] - #[cfg(unix)] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn signal_reported_right() { - use crate::os::unix::process::ExitStatusExt; - - let mut p = - Command::new("/bin/sh").arg("-c").arg("read a").stdin(Stdio::piped()).spawn().unwrap(); - p.kill().unwrap(); - match p.wait().unwrap().signal() { - Some(9) => {} - result => panic!("not terminated by signal 9 (instead, {:?})", result), - } - } - - pub fn run_output(mut cmd: Command) -> String { - let p = cmd.spawn(); - assert!(p.is_ok()); - let mut p = p.unwrap(); - assert!(p.stdout.is_some()); - let mut ret = String::new(); - p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap(); - assert!(p.wait().unwrap().success()); - return ret; - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn stdout_works() { - if cfg!(target_os = "windows") { - let mut cmd = Command::new("cmd"); - cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped()); - assert_eq!(run_output(cmd), "foobar\r\n"); - } else { - let mut cmd = Command::new("echo"); - cmd.arg("foobar").stdout(Stdio::piped()); - assert_eq!(run_output(cmd), "foobar\n"); - } - } - - #[test] - #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)] - fn set_current_dir_works() { - let mut cmd = Command::new("/bin/sh"); - cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped()); - assert_eq!(run_output(cmd), "/\n"); - } - - #[test] - #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)] - fn stdin_works() { - let mut p = Command::new("/bin/sh") - .arg("-c") - .arg("read line; echo $line") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap(); - drop(p.stdin.take()); - let mut out = String::new(); - p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap(); - assert!(p.wait().unwrap().success()); - assert_eq!(out, "foobar\n"); - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn test_process_status() { - let mut status = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap() - } else { - Command::new("false").status().unwrap() - }; - assert!(status.code() == Some(1)); - - status = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "exit 0"]).status().unwrap() - } else { - Command::new("true").status().unwrap() - }; - assert!(status.success()); - } - - #[test] - fn test_process_output_fail_to_start() { - match Command::new("/no-binary-by-this-name-should-exist").output() { - Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound), - Ok(..) => panic!(), - } - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn test_process_output_output() { - let Output { status, stdout, stderr } = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap() - } else { - Command::new("echo").arg("hello").output().unwrap() - }; - let output_str = str::from_utf8(&stdout).unwrap(); - - assert!(status.success()); - assert_eq!(output_str.trim().to_string(), "hello"); - assert_eq!(stderr, Vec::new()); - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn test_process_output_error() { - let Output { status, stdout, stderr } = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap() - } else { - Command::new("mkdir").arg("./").output().unwrap() - }; - - assert!(status.code() == Some(1)); - assert_eq!(stdout, Vec::new()); - assert!(!stderr.is_empty()); - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn test_finish_once() { - let mut prog = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap() - } else { - Command::new("false").spawn().unwrap() - }; - assert!(prog.wait().unwrap().code() == Some(1)); - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn test_finish_twice() { - let mut prog = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap() - } else { - Command::new("false").spawn().unwrap() - }; - assert!(prog.wait().unwrap().code() == Some(1)); - assert!(prog.wait().unwrap().code() == Some(1)); - } - - #[test] - #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] - fn test_wait_with_output_once() { - let prog = if cfg!(target_os = "windows") { - Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap() - } else { - Command::new("echo").arg("hello").stdout(Stdio::piped()).spawn().unwrap() - }; - - let Output { status, stdout, stderr } = prog.wait_with_output().unwrap(); - let output_str = str::from_utf8(&stdout).unwrap(); - - assert!(status.success()); - assert_eq!(output_str.trim().to_string(), "hello"); - assert_eq!(stderr, Vec::new()); - } - - #[cfg(all(unix, not(target_os = "android")))] - pub fn env_cmd() -> Command { - Command::new("env") - } - #[cfg(target_os = "android")] - pub fn env_cmd() -> Command { - let mut cmd = Command::new("/system/bin/sh"); - cmd.arg("-c").arg("set"); - cmd - } - - #[cfg(windows)] - pub fn env_cmd() -> Command { - let mut cmd = Command::new("cmd"); - cmd.arg("/c").arg("set"); - cmd - } - - #[test] - #[cfg_attr(target_os = "vxworks", ignore)] - fn test_override_env() { - use crate::env; - - // In some build environments (such as chrooted Nix builds), `env` can - // only be found in the explicitly-provided PATH env variable, not in - // default places such as /bin or /usr/bin. So we need to pass through - // PATH to our sub-process. - let mut cmd = env_cmd(); - cmd.env_clear().env("RUN_TEST_NEW_ENV", "123"); - if let Some(p) = env::var_os("PATH") { - cmd.env("PATH", &p); - } - let result = cmd.output().unwrap(); - let output = String::from_utf8_lossy(&result.stdout).to_string(); - - assert!( - output.contains("RUN_TEST_NEW_ENV=123"), - "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", - output - ); - } - - #[test] - #[cfg_attr(target_os = "vxworks", ignore)] - fn test_add_to_env() { - let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap(); - let output = String::from_utf8_lossy(&result.stdout).to_string(); - - assert!( - output.contains("RUN_TEST_NEW_ENV=123"), - "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", - output - ); - } - - #[test] - #[cfg_attr(target_os = "vxworks", ignore)] - fn test_capture_env_at_spawn() { - use crate::env; - - let mut cmd = env_cmd(); - cmd.env("RUN_TEST_NEW_ENV1", "123"); - - // This variable will not be present if the environment has already - // been captured above. - env::set_var("RUN_TEST_NEW_ENV2", "456"); - let result = cmd.output().unwrap(); - env::remove_var("RUN_TEST_NEW_ENV2"); - - let output = String::from_utf8_lossy(&result.stdout).to_string(); - - assert!( - output.contains("RUN_TEST_NEW_ENV1=123"), - "didn't find RUN_TEST_NEW_ENV1 inside of:\n\n{}", - output - ); - assert!( - output.contains("RUN_TEST_NEW_ENV2=456"), - "didn't find RUN_TEST_NEW_ENV2 inside of:\n\n{}", - output - ); - } - - // Regression tests for #30858. - #[test] - fn test_interior_nul_in_progname_is_error() { - match Command::new("has-some-\0\0s-inside").spawn() { - Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), - Ok(_) => panic!(), - } - } - - #[test] - fn test_interior_nul_in_arg_is_error() { - match Command::new("echo").arg("has-some-\0\0s-inside").spawn() { - Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), - Ok(_) => panic!(), - } - } - - #[test] - fn test_interior_nul_in_args_is_error() { - match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() { - Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), - Ok(_) => panic!(), - } - } - - #[test] - fn test_interior_nul_in_current_dir_is_error() { - match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() { - Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), - Ok(_) => panic!(), - } - } - - // Regression tests for #30862. - #[test] - #[cfg_attr(target_os = "vxworks", ignore)] - fn test_interior_nul_in_env_key_is_error() { - match env_cmd().env("has-some-\0\0s-inside", "value").spawn() { - Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), - Ok(_) => panic!(), - } - } - - #[test] - #[cfg_attr(target_os = "vxworks", ignore)] - fn test_interior_nul_in_env_value_is_error() { - match env_cmd().env("key", "has-some-\0\0s-inside").spawn() { - Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), - Ok(_) => panic!(), - } - } - - /// Tests that process creation flags work by debugging a process. - /// Other creation flags make it hard or impossible to detect - /// behavioral changes in the process. - #[test] - #[cfg(windows)] - fn test_creation_flags() { - use crate::os::windows::process::CommandExt; - use crate::sys::c::{BOOL, DWORD, INFINITE}; - #[repr(C, packed)] - struct DEBUG_EVENT { - pub event_code: DWORD, - pub process_id: DWORD, - pub thread_id: DWORD, - // This is a union in the real struct, but we don't - // need this data for the purposes of this test. - pub _junk: [u8; 164], - } - - extern "system" { - fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL; - fn ContinueDebugEvent( - dwProcessId: DWORD, - dwThreadId: DWORD, - dwContinueStatus: DWORD, - ) -> BOOL; - } - - const DEBUG_PROCESS: DWORD = 1; - const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5; - const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001; - - let mut child = Command::new("cmd") - .creation_flags(DEBUG_PROCESS) - .stdin(Stdio::piped()) - .spawn() - .unwrap(); - child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap(); - let mut events = 0; - let mut event = DEBUG_EVENT { event_code: 0, process_id: 0, thread_id: 0, _junk: [0; 164] }; - loop { - if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 { - panic!("WaitForDebugEvent failed!"); - } - events += 1; - - if event.event_code == EXIT_PROCESS_DEBUG_EVENT { - break; - } - - if unsafe { - ContinueDebugEvent(event.process_id, event.thread_id, DBG_EXCEPTION_NOT_HANDLED) - } == 0 - { - panic!("ContinueDebugEvent failed!"); - } - } - assert!(events > 0); - } - - #[test] - fn test_command_implements_send_sync() { - fn take_send_sync_type<T: Send + Sync>(_: T) {} - take_send_sync_type(Command::new("")) - } -} diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs new file mode 100644 index 00000000000..05e093434be --- /dev/null +++ b/library/std/src/process/tests.rs @@ -0,0 +1,401 @@ +use crate::io::prelude::*; + +use super::{Command, Output, Stdio}; +use crate::io::ErrorKind; +use crate::str; + +// FIXME(#10380) these tests should not all be ignored on android. + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn smoke() { + let p = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "exit 0"]).spawn() + } else { + Command::new("true").spawn() + }; + assert!(p.is_ok()); + let mut p = p.unwrap(); + assert!(p.wait().unwrap().success()); +} + +#[test] +#[cfg_attr(target_os = "android", ignore)] +fn smoke_failure() { + match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() { + Ok(..) => panic!(), + Err(..) => {} + } +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn exit_reported_right() { + let p = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "exit 1"]).spawn() + } else { + Command::new("false").spawn() + }; + assert!(p.is_ok()); + let mut p = p.unwrap(); + assert!(p.wait().unwrap().code() == Some(1)); + drop(p.wait()); +} + +#[test] +#[cfg(unix)] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn signal_reported_right() { + use crate::os::unix::process::ExitStatusExt; + + let mut p = + Command::new("/bin/sh").arg("-c").arg("read a").stdin(Stdio::piped()).spawn().unwrap(); + p.kill().unwrap(); + match p.wait().unwrap().signal() { + Some(9) => {} + result => panic!("not terminated by signal 9 (instead, {:?})", result), + } +} + +pub fn run_output(mut cmd: Command) -> String { + let p = cmd.spawn(); + assert!(p.is_ok()); + let mut p = p.unwrap(); + assert!(p.stdout.is_some()); + let mut ret = String::new(); + p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap(); + assert!(p.wait().unwrap().success()); + return ret; +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn stdout_works() { + if cfg!(target_os = "windows") { + let mut cmd = Command::new("cmd"); + cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped()); + assert_eq!(run_output(cmd), "foobar\r\n"); + } else { + let mut cmd = Command::new("echo"); + cmd.arg("foobar").stdout(Stdio::piped()); + assert_eq!(run_output(cmd), "foobar\n"); + } +} + +#[test] +#[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)] +fn set_current_dir_works() { + let mut cmd = Command::new("/bin/sh"); + cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped()); + assert_eq!(run_output(cmd), "/\n"); +} + +#[test] +#[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)] +fn stdin_works() { + let mut p = Command::new("/bin/sh") + .arg("-c") + .arg("read line; echo $line") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap(); + drop(p.stdin.take()); + let mut out = String::new(); + p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap(); + assert!(p.wait().unwrap().success()); + assert_eq!(out, "foobar\n"); +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn test_process_status() { + let mut status = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap() + } else { + Command::new("false").status().unwrap() + }; + assert!(status.code() == Some(1)); + + status = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "exit 0"]).status().unwrap() + } else { + Command::new("true").status().unwrap() + }; + assert!(status.success()); +} + +#[test] +fn test_process_output_fail_to_start() { + match Command::new("/no-binary-by-this-name-should-exist").output() { + Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound), + Ok(..) => panic!(), + } +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn test_process_output_output() { + let Output { status, stdout, stderr } = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap() + } else { + Command::new("echo").arg("hello").output().unwrap() + }; + let output_str = str::from_utf8(&stdout).unwrap(); + + assert!(status.success()); + assert_eq!(output_str.trim().to_string(), "hello"); + assert_eq!(stderr, Vec::new()); +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn test_process_output_error() { + let Output { status, stdout, stderr } = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap() + } else { + Command::new("mkdir").arg("./").output().unwrap() + }; + + assert!(status.code() == Some(1)); + assert_eq!(stdout, Vec::new()); + assert!(!stderr.is_empty()); +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn test_finish_once() { + let mut prog = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap() + } else { + Command::new("false").spawn().unwrap() + }; + assert!(prog.wait().unwrap().code() == Some(1)); +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn test_finish_twice() { + let mut prog = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap() + } else { + Command::new("false").spawn().unwrap() + }; + assert!(prog.wait().unwrap().code() == Some(1)); + assert!(prog.wait().unwrap().code() == Some(1)); +} + +#[test] +#[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] +fn test_wait_with_output_once() { + let prog = if cfg!(target_os = "windows") { + Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap() + } else { + Command::new("echo").arg("hello").stdout(Stdio::piped()).spawn().unwrap() + }; + + let Output { status, stdout, stderr } = prog.wait_with_output().unwrap(); + let output_str = str::from_utf8(&stdout).unwrap(); + + assert!(status.success()); + assert_eq!(output_str.trim().to_string(), "hello"); + assert_eq!(stderr, Vec::new()); +} + +#[cfg(all(unix, not(target_os = "android")))] +pub fn env_cmd() -> Command { + Command::new("env") +} +#[cfg(target_os = "android")] +pub fn env_cmd() -> Command { + let mut cmd = Command::new("/system/bin/sh"); + cmd.arg("-c").arg("set"); + cmd +} + +#[cfg(windows)] +pub fn env_cmd() -> Command { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg("set"); + cmd +} + +#[test] +#[cfg_attr(target_os = "vxworks", ignore)] +fn test_override_env() { + use crate::env; + + // In some build environments (such as chrooted Nix builds), `env` can + // only be found in the explicitly-provided PATH env variable, not in + // default places such as /bin or /usr/bin. So we need to pass through + // PATH to our sub-process. + let mut cmd = env_cmd(); + cmd.env_clear().env("RUN_TEST_NEW_ENV", "123"); + if let Some(p) = env::var_os("PATH") { + cmd.env("PATH", &p); + } + let result = cmd.output().unwrap(); + let output = String::from_utf8_lossy(&result.stdout).to_string(); + + assert!( + output.contains("RUN_TEST_NEW_ENV=123"), + "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", + output + ); +} + +#[test] +#[cfg_attr(target_os = "vxworks", ignore)] +fn test_add_to_env() { + let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap(); + let output = String::from_utf8_lossy(&result.stdout).to_string(); + + assert!( + output.contains("RUN_TEST_NEW_ENV=123"), + "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", + output + ); +} + +#[test] +#[cfg_attr(target_os = "vxworks", ignore)] +fn test_capture_env_at_spawn() { + use crate::env; + + let mut cmd = env_cmd(); + cmd.env("RUN_TEST_NEW_ENV1", "123"); + + // This variable will not be present if the environment has already + // been captured above. + env::set_var("RUN_TEST_NEW_ENV2", "456"); + let result = cmd.output().unwrap(); + env::remove_var("RUN_TEST_NEW_ENV2"); + + let output = String::from_utf8_lossy(&result.stdout).to_string(); + + assert!( + output.contains("RUN_TEST_NEW_ENV1=123"), + "didn't find RUN_TEST_NEW_ENV1 inside of:\n\n{}", + output + ); + assert!( + output.contains("RUN_TEST_NEW_ENV2=456"), + "didn't find RUN_TEST_NEW_ENV2 inside of:\n\n{}", + output + ); +} + +// Regression tests for #30858. +#[test] +fn test_interior_nul_in_progname_is_error() { + match Command::new("has-some-\0\0s-inside").spawn() { + Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), + Ok(_) => panic!(), + } +} + +#[test] +fn test_interior_nul_in_arg_is_error() { + match Command::new("echo").arg("has-some-\0\0s-inside").spawn() { + Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), + Ok(_) => panic!(), + } +} + +#[test] +fn test_interior_nul_in_args_is_error() { + match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() { + Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), + Ok(_) => panic!(), + } +} + +#[test] +fn test_interior_nul_in_current_dir_is_error() { + match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() { + Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), + Ok(_) => panic!(), + } +} + +// Regression tests for #30862. +#[test] +#[cfg_attr(target_os = "vxworks", ignore)] +fn test_interior_nul_in_env_key_is_error() { + match env_cmd().env("has-some-\0\0s-inside", "value").spawn() { + Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), + Ok(_) => panic!(), + } +} + +#[test] +#[cfg_attr(target_os = "vxworks", ignore)] +fn test_interior_nul_in_env_value_is_error() { + match env_cmd().env("key", "has-some-\0\0s-inside").spawn() { + Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), + Ok(_) => panic!(), + } +} + +/// Tests that process creation flags work by debugging a process. +/// Other creation flags make it hard or impossible to detect +/// behavioral changes in the process. +#[test] +#[cfg(windows)] +fn test_creation_flags() { + use crate::os::windows::process::CommandExt; + use crate::sys::c::{BOOL, DWORD, INFINITE}; + #[repr(C, packed)] + struct DEBUG_EVENT { + pub event_code: DWORD, + pub process_id: DWORD, + pub thread_id: DWORD, + // This is a union in the real struct, but we don't + // need this data for the purposes of this test. + pub _junk: [u8; 164], + } + + extern "system" { + fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL; + fn ContinueDebugEvent( + dwProcessId: DWORD, + dwThreadId: DWORD, + dwContinueStatus: DWORD, + ) -> BOOL; + } + + const DEBUG_PROCESS: DWORD = 1; + const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5; + const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001; + + let mut child = + Command::new("cmd").creation_flags(DEBUG_PROCESS).stdin(Stdio::piped()).spawn().unwrap(); + child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap(); + let mut events = 0; + let mut event = DEBUG_EVENT { event_code: 0, process_id: 0, thread_id: 0, _junk: [0; 164] }; + loop { + if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 { + panic!("WaitForDebugEvent failed!"); + } + events += 1; + + if event.event_code == EXIT_PROCESS_DEBUG_EVENT { + break; + } + + if unsafe { + ContinueDebugEvent(event.process_id, event.thread_id, DBG_EXCEPTION_NOT_HANDLED) + } == 0 + { + panic!("ContinueDebugEvent failed!"); + } + } + assert!(events > 0); +} + +#[test] +fn test_command_implements_send_sync() { + fn take_send_sync_type<T: Send + Sync>(_: T) {} + take_send_sync_type(Command::new("")) +} diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs index 23c989fd2fd..5d434791e9a 100644 --- a/library/std/src/sync/barrier.rs +++ b/library/std/src/sync/barrier.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::fmt; use crate::sync::{Condvar, Mutex}; @@ -174,42 +177,3 @@ impl BarrierWaitResult { self.0 } } - -#[cfg(test)] -mod tests { - use crate::sync::mpsc::{channel, TryRecvError}; - use crate::sync::{Arc, Barrier}; - use crate::thread; - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn test_barrier() { - const N: usize = 10; - - let barrier = Arc::new(Barrier::new(N)); - let (tx, rx) = channel(); - - for _ in 0..N - 1 { - let c = barrier.clone(); - let tx = tx.clone(); - thread::spawn(move || { - tx.send(c.wait().is_leader()).unwrap(); - }); - } - - // At this point, all spawned threads should be blocked, - // so we shouldn't get anything from the port - assert!(matches!(rx.try_recv(), Err(TryRecvError::Empty))); - - let mut leader_found = barrier.wait().is_leader(); - - // Now, the barrier is cleared and we should get data. - for _ in 0..N - 1 { - if rx.recv().unwrap() { - assert!(!leader_found); - leader_found = true; - } - } - assert!(leader_found); - } -} diff --git a/library/std/src/sync/barrier/tests.rs b/library/std/src/sync/barrier/tests.rs new file mode 100644 index 00000000000..834a3e75158 --- /dev/null +++ b/library/std/src/sync/barrier/tests.rs @@ -0,0 +1,35 @@ +use crate::sync::mpsc::{channel, TryRecvError}; +use crate::sync::{Arc, Barrier}; +use crate::thread; + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn test_barrier() { + const N: usize = 10; + + let barrier = Arc::new(Barrier::new(N)); + let (tx, rx) = channel(); + + for _ in 0..N - 1 { + let c = barrier.clone(); + let tx = tx.clone(); + thread::spawn(move || { + tx.send(c.wait().is_leader()).unwrap(); + }); + } + + // At this point, all spawned threads should be blocked, + // so we shouldn't get anything from the port + assert!(matches!(rx.try_recv(), Err(TryRecvError::Empty))); + + let mut leader_found = barrier.wait().is_leader(); + + // Now, the barrier is cleared and we should get data. + for _ in 0..N - 1 { + if rx.recv().unwrap() { + assert!(!leader_found); + leader_found = true; + } + } + assert!(leader_found); +} diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs index 4efd86aa3ed..651f813b3e2 100644 --- a/library/std/src/sync/condvar.rs +++ b/library/std/src/sync/condvar.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::fmt; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::{mutex, MutexGuard, PoisonError}; @@ -598,218 +601,3 @@ impl Drop for Condvar { unsafe { self.inner.destroy() } } } - -#[cfg(test)] -mod tests { - use crate::sync::atomic::{AtomicBool, Ordering}; - use crate::sync::mpsc::channel; - use crate::sync::{Arc, Condvar, Mutex}; - use crate::thread; - use crate::time::Duration; - - #[test] - fn smoke() { - let c = Condvar::new(); - c.notify_one(); - c.notify_all(); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn notify_one() { - let m = Arc::new(Mutex::new(())); - let m2 = m.clone(); - let c = Arc::new(Condvar::new()); - let c2 = c.clone(); - - let g = m.lock().unwrap(); - let _t = thread::spawn(move || { - let _g = m2.lock().unwrap(); - c2.notify_one(); - }); - let g = c.wait(g).unwrap(); - drop(g); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn notify_all() { - const N: usize = 10; - - let data = Arc::new((Mutex::new(0), Condvar::new())); - let (tx, rx) = channel(); - for _ in 0..N { - let data = data.clone(); - let tx = tx.clone(); - thread::spawn(move || { - let &(ref lock, ref cond) = &*data; - let mut cnt = lock.lock().unwrap(); - *cnt += 1; - if *cnt == N { - tx.send(()).unwrap(); - } - while *cnt != 0 { - cnt = cond.wait(cnt).unwrap(); - } - tx.send(()).unwrap(); - }); - } - drop(tx); - - let &(ref lock, ref cond) = &*data; - rx.recv().unwrap(); - let mut cnt = lock.lock().unwrap(); - *cnt = 0; - cond.notify_all(); - drop(cnt); - - for _ in 0..N { - rx.recv().unwrap(); - } - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_while() { - let pair = Arc::new((Mutex::new(false), Condvar::new())); - let pair2 = pair.clone(); - - // Inside of our lock, spawn a new thread, and then wait for it to start. - thread::spawn(move || { - let &(ref lock, ref cvar) = &*pair2; - let mut started = lock.lock().unwrap(); - *started = true; - // We notify the condvar that the value has changed. - cvar.notify_one(); - }); - - // Wait for the thread to start up. - let &(ref lock, ref cvar) = &*pair; - let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started); - assert!(*guard.unwrap()); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_timeout_wait() { - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); - - loop { - let g = m.lock().unwrap(); - let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap(); - // spurious wakeups mean this isn't necessarily true - // so execute test again, if not timeout - if !no_timeout.timed_out() { - continue; - } - - break; - } - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_timeout_while_wait() { - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); - - let g = m.lock().unwrap(); - let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap(); - // no spurious wakeups. ensure it timed-out - assert!(wait.timed_out()); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_timeout_while_instant_satisfy() { - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); - - let g = m.lock().unwrap(); - let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap(); - // ensure it didn't time-out even if we were not given any time. - assert!(!wait.timed_out()); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_timeout_while_wake() { - let pair = Arc::new((Mutex::new(false), Condvar::new())); - let pair_copy = pair.clone(); - - let &(ref m, ref c) = &*pair; - let g = m.lock().unwrap(); - let _t = thread::spawn(move || { - let &(ref lock, ref cvar) = &*pair_copy; - let mut started = lock.lock().unwrap(); - thread::sleep(Duration::from_millis(1)); - *started = true; - cvar.notify_one(); - }); - let (g2, wait) = c - .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified) - .unwrap(); - // ensure it didn't time-out even if we were not given any time. - assert!(!wait.timed_out()); - assert!(*g2); - } - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn wait_timeout_wake() { - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); - - loop { - let g = m.lock().unwrap(); - - let c2 = c.clone(); - let m2 = m.clone(); - - let notified = Arc::new(AtomicBool::new(false)); - let notified_copy = notified.clone(); - - let t = thread::spawn(move || { - let _g = m2.lock().unwrap(); - thread::sleep(Duration::from_millis(1)); - notified_copy.store(true, Ordering::SeqCst); - c2.notify_one(); - }); - let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap(); - assert!(!timeout_res.timed_out()); - // spurious wakeups mean this isn't necessarily true - // so execute test again, if not notified - if !notified.load(Ordering::SeqCst) { - t.join().unwrap(); - continue; - } - drop(g); - - t.join().unwrap(); - - break; - } - } - - #[test] - #[should_panic] - #[cfg_attr(target_os = "emscripten", ignore)] - fn two_mutexes() { - let m = Arc::new(Mutex::new(())); - let m2 = m.clone(); - let c = Arc::new(Condvar::new()); - let c2 = c.clone(); - - let mut g = m.lock().unwrap(); - let _t = thread::spawn(move || { - let _g = m2.lock().unwrap(); - c2.notify_one(); - }); - g = c.wait(g).unwrap(); - drop(g); - - let m = Mutex::new(()); - let _ = c.wait(m.lock().unwrap()).unwrap(); - } -} diff --git a/library/std/src/sync/condvar/tests.rs b/library/std/src/sync/condvar/tests.rs new file mode 100644 index 00000000000..86d099ee3a1 --- /dev/null +++ b/library/std/src/sync/condvar/tests.rs @@ -0,0 +1,211 @@ +use crate::sync::atomic::{AtomicBool, Ordering}; +use crate::sync::mpsc::channel; +use crate::sync::{Arc, Condvar, Mutex}; +use crate::thread; +use crate::time::Duration; + +#[test] +fn smoke() { + let c = Condvar::new(); + c.notify_one(); + c.notify_all(); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn notify_one() { + let m = Arc::new(Mutex::new(())); + let m2 = m.clone(); + let c = Arc::new(Condvar::new()); + let c2 = c.clone(); + + let g = m.lock().unwrap(); + let _t = thread::spawn(move || { + let _g = m2.lock().unwrap(); + c2.notify_one(); + }); + let g = c.wait(g).unwrap(); + drop(g); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn notify_all() { + const N: usize = 10; + + let data = Arc::new((Mutex::new(0), Condvar::new())); + let (tx, rx) = channel(); + for _ in 0..N { + let data = data.clone(); + let tx = tx.clone(); + thread::spawn(move || { + let &(ref lock, ref cond) = &*data; + let mut cnt = lock.lock().unwrap(); + *cnt += 1; + if *cnt == N { + tx.send(()).unwrap(); + } + while *cnt != 0 { + cnt = cond.wait(cnt).unwrap(); + } + tx.send(()).unwrap(); + }); + } + drop(tx); + + let &(ref lock, ref cond) = &*data; + rx.recv().unwrap(); + let mut cnt = lock.lock().unwrap(); + *cnt = 0; + cond.notify_all(); + drop(cnt); + + for _ in 0..N { + rx.recv().unwrap(); + } +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn wait_while() { + let pair = Arc::new((Mutex::new(false), Condvar::new())); + let pair2 = pair.clone(); + + // Inside of our lock, spawn a new thread, and then wait for it to start. + thread::spawn(move || { + let &(ref lock, ref cvar) = &*pair2; + let mut started = lock.lock().unwrap(); + *started = true; + // We notify the condvar that the value has changed. + cvar.notify_one(); + }); + + // Wait for the thread to start up. + let &(ref lock, ref cvar) = &*pair; + let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started); + assert!(*guard.unwrap()); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn wait_timeout_wait() { + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + loop { + let g = m.lock().unwrap(); + let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap(); + // spurious wakeups mean this isn't necessarily true + // so execute test again, if not timeout + if !no_timeout.timed_out() { + continue; + } + + break; + } +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn wait_timeout_while_wait() { + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + let g = m.lock().unwrap(); + let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap(); + // no spurious wakeups. ensure it timed-out + assert!(wait.timed_out()); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn wait_timeout_while_instant_satisfy() { + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + let g = m.lock().unwrap(); + let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap(); + // ensure it didn't time-out even if we were not given any time. + assert!(!wait.timed_out()); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn wait_timeout_while_wake() { + let pair = Arc::new((Mutex::new(false), Condvar::new())); + let pair_copy = pair.clone(); + + let &(ref m, ref c) = &*pair; + let g = m.lock().unwrap(); + let _t = thread::spawn(move || { + let &(ref lock, ref cvar) = &*pair_copy; + let mut started = lock.lock().unwrap(); + thread::sleep(Duration::from_millis(1)); + *started = true; + cvar.notify_one(); + }); + let (g2, wait) = c + .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified) + .unwrap(); + // ensure it didn't time-out even if we were not given any time. + assert!(!wait.timed_out()); + assert!(*g2); +} + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] +fn wait_timeout_wake() { + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + loop { + let g = m.lock().unwrap(); + + let c2 = c.clone(); + let m2 = m.clone(); + + let notified = Arc::new(AtomicBool::new(false)); + let notified_copy = notified.clone(); + + let t = thread::spawn(move || { + let _g = m2.lock().unwrap(); + thread::sleep(Duration::from_millis(1)); + notified_copy.store(true, Ordering::SeqCst); + c2.notify_one(); + }); + let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap(); + assert!(!timeout_res.timed_out()); + // spurious wakeups mean this isn't necessarily true + // so execute test again, if not notified + if !notified.load(Ordering::SeqCst) { + t.join().unwrap(); + continue; + } + drop(g); + + t.join().unwrap(); + + break; + } +} + +#[test] +#[should_panic] +#[cfg_attr(target_os = "emscripten", ignore)] +fn two_mutexes() { + let m = Arc::new(Mutex::new(())); + let m2 = m.clone(); + let c = Arc::new(Condvar::new()); + let c2 = c.clone(); + + let mut g = m.lock().unwrap(); + let _t = thread::spawn(move || { + let _g = m2.lock().unwrap(); + c2.notify_one(); + }); + g = c.wait(g).unwrap(); + drop(g); + + let m = Mutex::new(()); + let _ = c.wait(m.lock().unwrap()).unwrap(); +} diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index ac83017d9e1..073f969bbe2 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -108,6 +108,12 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + +#[cfg(all(test, not(target_os = "emscripten")))] +mod sync_tests; + // A description of how Rust's channel implementation works // // Channels are supposed to be the basic building block for all other @@ -1606,1364 +1612,3 @@ impl From<RecvError> for RecvTimeoutError { } } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use super::*; - use crate::env; - use crate::thread; - use crate::time::{Duration, Instant}; - - pub fn stress_factor() -> usize { - match env::var("RUST_TEST_STRESS") { - Ok(val) => val.parse().unwrap(), - Err(..) => 1, - } - } - - #[test] - fn smoke() { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn drop_full() { - let (tx, _rx) = channel::<Box<isize>>(); - tx.send(box 1).unwrap(); - } - - #[test] - fn drop_full_shared() { - let (tx, _rx) = channel::<Box<isize>>(); - drop(tx.clone()); - drop(tx.clone()); - tx.send(box 1).unwrap(); - } - - #[test] - fn smoke_shared() { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - let tx = tx.clone(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn smoke_threads() { - let (tx, rx) = channel::<i32>(); - let _t = thread::spawn(move || { - tx.send(1).unwrap(); - }); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn smoke_port_gone() { - let (tx, rx) = channel::<i32>(); - drop(rx); - assert!(tx.send(1).is_err()); - } - - #[test] - fn smoke_shared_port_gone() { - let (tx, rx) = channel::<i32>(); - drop(rx); - assert!(tx.send(1).is_err()) - } - - #[test] - fn smoke_shared_port_gone2() { - let (tx, rx) = channel::<i32>(); - drop(rx); - let tx2 = tx.clone(); - drop(tx); - assert!(tx2.send(1).is_err()); - } - - #[test] - fn port_gone_concurrent() { - let (tx, rx) = channel::<i32>(); - let _t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() {} - } - - #[test] - fn port_gone_concurrent_shared() { - let (tx, rx) = channel::<i32>(); - let tx2 = tx.clone(); - let _t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() && tx2.send(1).is_ok() {} - } - - #[test] - fn smoke_chan_gone() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn smoke_chan_gone_shared() { - let (tx, rx) = channel::<()>(); - let tx2 = tx.clone(); - drop(tx); - drop(tx2); - assert!(rx.recv().is_err()); - } - - #[test] - fn chan_gone_concurrent() { - let (tx, rx) = channel::<i32>(); - let _t = thread::spawn(move || { - tx.send(1).unwrap(); - tx.send(1).unwrap(); - }); - while rx.recv().is_ok() {} - } - - #[test] - fn stress() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - for _ in 0..10000 { - tx.send(1).unwrap(); - } - }); - for _ in 0..10000 { - assert_eq!(rx.recv().unwrap(), 1); - } - t.join().ok().expect("thread panicked"); - } - - #[test] - fn stress_shared() { - const AMT: u32 = 10000; - const NTHREADS: u32 = 8; - let (tx, rx) = channel::<i32>(); - - let t = thread::spawn(move || { - for _ in 0..AMT * NTHREADS { - assert_eq!(rx.recv().unwrap(), 1); - } - match rx.try_recv() { - Ok(..) => panic!(), - _ => {} - } - }); - - for _ in 0..NTHREADS { - let tx = tx.clone(); - thread::spawn(move || { - for _ in 0..AMT { - tx.send(1).unwrap(); - } - }); - } - drop(tx); - t.join().ok().expect("thread panicked"); - } - - #[test] - fn send_from_outside_runtime() { - let (tx1, rx1) = channel::<()>(); - let (tx2, rx2) = channel::<i32>(); - let t1 = thread::spawn(move || { - tx1.send(()).unwrap(); - for _ in 0..40 { - assert_eq!(rx2.recv().unwrap(), 1); - } - }); - rx1.recv().unwrap(); - let t2 = thread::spawn(move || { - for _ in 0..40 { - tx2.send(1).unwrap(); - } - }); - t1.join().ok().expect("thread panicked"); - t2.join().ok().expect("thread panicked"); - } - - #[test] - fn recv_from_outside_runtime() { - let (tx, rx) = channel::<i32>(); - let t = thread::spawn(move || { - for _ in 0..40 { - assert_eq!(rx.recv().unwrap(), 1); - } - }); - for _ in 0..40 { - tx.send(1).unwrap(); - } - t.join().ok().expect("thread panicked"); - } - - #[test] - fn no_runtime() { - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<i32>(); - let t1 = thread::spawn(move || { - assert_eq!(rx1.recv().unwrap(), 1); - tx2.send(2).unwrap(); - }); - let t2 = thread::spawn(move || { - tx1.send(1).unwrap(); - assert_eq!(rx2.recv().unwrap(), 2); - }); - t1.join().ok().expect("thread panicked"); - t2.join().ok().expect("thread panicked"); - } - - #[test] - fn oneshot_single_thread_close_port_first() { - // Simple test of closing without sending - let (_tx, rx) = channel::<i32>(); - drop(rx); - } - - #[test] - fn oneshot_single_thread_close_chan_first() { - // Simple test of closing without sending - let (tx, _rx) = channel::<i32>(); - drop(tx); - } - - #[test] - fn oneshot_single_thread_send_port_close() { - // Testing that the sender cleans up the payload if receiver is closed - let (tx, rx) = channel::<Box<i32>>(); - drop(rx); - assert!(tx.send(box 0).is_err()); - } - - #[test] - fn oneshot_single_thread_recv_chan_close() { - // Receiving on a closed chan will panic - let res = thread::spawn(move || { - let (tx, rx) = channel::<i32>(); - drop(tx); - rx.recv().unwrap(); - }) - .join(); - // What is our res? - assert!(res.is_err()); - } - - #[test] - fn oneshot_single_thread_send_then_recv() { - let (tx, rx) = channel::<Box<i32>>(); - tx.send(box 10).unwrap(); - assert!(*rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_open() { - let (tx, rx) = channel::<i32>(); - assert!(tx.send(10).is_ok()); - assert!(rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_closed() { - let (tx, rx) = channel::<i32>(); - drop(rx); - assert!(tx.send(10).is_err()); - } - - #[test] - fn oneshot_single_thread_try_recv_open() { - let (tx, rx) = channel::<i32>(); - tx.send(10).unwrap(); - assert!(rx.recv() == Ok(10)); - } - - #[test] - fn oneshot_single_thread_try_recv_closed() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn oneshot_single_thread_peek_data() { - let (tx, rx) = channel::<i32>(); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - tx.send(10).unwrap(); - assert_eq!(rx.try_recv(), Ok(10)); - } - - #[test] - fn oneshot_single_thread_peek_close() { - let (tx, rx) = channel::<i32>(); - drop(tx); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - } - - #[test] - fn oneshot_single_thread_peek_open() { - let (_tx, rx) = channel::<i32>(); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - } - - #[test] - fn oneshot_multi_task_recv_then_send() { - let (tx, rx) = channel::<Box<i32>>(); - let _t = thread::spawn(move || { - assert!(*rx.recv().unwrap() == 10); - }); - - tx.send(box 10).unwrap(); - } - - #[test] - fn oneshot_multi_task_recv_then_close() { - let (tx, rx) = channel::<Box<i32>>(); - let _t = thread::spawn(move || { - drop(tx); - }); - let res = thread::spawn(move || { - assert!(*rx.recv().unwrap() == 10); - }) - .join(); - assert!(res.is_err()); - } - - #[test] - fn oneshot_multi_thread_close_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = channel::<i32>(); - let _t = thread::spawn(move || { - drop(rx); - }); - drop(tx); - } - } - - #[test] - fn oneshot_multi_thread_send_close_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = channel::<i32>(); - let _t = thread::spawn(move || { - drop(rx); - }); - let _ = thread::spawn(move || { - tx.send(1).unwrap(); - }) - .join(); - } - } - - #[test] - fn oneshot_multi_thread_recv_close_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = channel::<i32>(); - thread::spawn(move || { - let res = thread::spawn(move || { - rx.recv().unwrap(); - }) - .join(); - assert!(res.is_err()); - }); - let _t = thread::spawn(move || { - thread::spawn(move || { - drop(tx); - }); - }); - } - } - - #[test] - fn oneshot_multi_thread_send_recv_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = channel::<Box<isize>>(); - let _t = thread::spawn(move || { - tx.send(box 10).unwrap(); - }); - assert!(*rx.recv().unwrap() == 10); - } - } - - #[test] - fn stream_send_recv_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = channel(); - - send(tx, 0); - recv(rx, 0); - - fn send(tx: Sender<Box<i32>>, i: i32) { - if i == 10 { - return; - } - - thread::spawn(move || { - tx.send(box i).unwrap(); - send(tx, i + 1); - }); - } - - fn recv(rx: Receiver<Box<i32>>, i: i32) { - if i == 10 { - return; - } - - thread::spawn(move || { - assert!(*rx.recv().unwrap() == i); - recv(rx, i + 1); - }); - } - } - } - - #[test] - fn oneshot_single_thread_recv_timeout() { - let (tx, rx) = channel(); - tx.send(()).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); - tx.send(()).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); - } - - #[test] - fn stress_recv_timeout_two_threads() { - let (tx, rx) = channel(); - let stress = stress_factor() + 100; - let timeout = Duration::from_millis(100); - - thread::spawn(move || { - for i in 0..stress { - if i % 2 == 0 { - thread::sleep(timeout * 2); - } - tx.send(1usize).unwrap(); - } - }); - - let mut recv_count = 0; - loop { - match rx.recv_timeout(timeout) { - Ok(n) => { - assert_eq!(n, 1usize); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, stress); - } - - #[test] - fn recv_timeout_upgrade() { - let (tx, rx) = channel::<()>(); - let timeout = Duration::from_millis(1); - let _tx_clone = tx.clone(); - - let start = Instant::now(); - assert_eq!(rx.recv_timeout(timeout), Err(RecvTimeoutError::Timeout)); - assert!(Instant::now() >= start + timeout); - } - - #[test] - fn stress_recv_timeout_shared() { - let (tx, rx) = channel(); - let stress = stress_factor() + 100; - - for i in 0..stress { - let tx = tx.clone(); - thread::spawn(move || { - thread::sleep(Duration::from_millis(i as u64 * 10)); - tx.send(1usize).unwrap(); - }); - } - - drop(tx); - - let mut recv_count = 0; - loop { - match rx.recv_timeout(Duration::from_millis(10)) { - Ok(n) => { - assert_eq!(n, 1usize); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, stress); - } - - #[test] - fn very_long_recv_timeout_wont_panic() { - let (tx, rx) = channel::<()>(); - let join_handle = thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::MAX))); - thread::sleep(Duration::from_secs(1)); - assert!(tx.send(()).is_ok()); - assert_eq!(join_handle.join().unwrap(), Ok(())); - } - - #[test] - fn recv_a_lot() { - // Regression test that we don't run out of stack in scheduler context - let (tx, rx) = channel(); - for _ in 0..10000 { - tx.send(()).unwrap(); - } - for _ in 0..10000 { - rx.recv().unwrap(); - } - } - - #[test] - fn shared_recv_timeout() { - let (tx, rx) = channel(); - let total = 5; - for _ in 0..total { - let tx = tx.clone(); - thread::spawn(move || { - tx.send(()).unwrap(); - }); - } - - for _ in 0..total { - rx.recv().unwrap(); - } - - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); - tx.send(()).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); - } - - #[test] - fn shared_chan_stress() { - let (tx, rx) = channel(); - let total = stress_factor() + 100; - for _ in 0..total { - let tx = tx.clone(); - thread::spawn(move || { - tx.send(()).unwrap(); - }); - } - - for _ in 0..total { - rx.recv().unwrap(); - } - } - - #[test] - fn test_nested_recv_iter() { - let (tx, rx) = channel::<i32>(); - let (total_tx, total_rx) = channel::<i32>(); - - let _t = thread::spawn(move || { - let mut acc = 0; - for x in rx.iter() { - acc += x; - } - total_tx.send(acc).unwrap(); - }); - - tx.send(3).unwrap(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - drop(tx); - assert_eq!(total_rx.recv().unwrap(), 6); - } - - #[test] - fn test_recv_iter_break() { - let (tx, rx) = channel::<i32>(); - let (count_tx, count_rx) = channel(); - - let _t = thread::spawn(move || { - let mut count = 0; - for x in rx.iter() { - if count >= 3 { - break; - } else { - count += x; - } - } - count_tx.send(count).unwrap(); - }); - - tx.send(2).unwrap(); - tx.send(2).unwrap(); - tx.send(2).unwrap(); - let _ = tx.send(2); - drop(tx); - assert_eq!(count_rx.recv().unwrap(), 4); - } - - #[test] - fn test_recv_try_iter() { - let (request_tx, request_rx) = channel(); - let (response_tx, response_rx) = channel(); - - // Request `x`s until we have `6`. - let t = thread::spawn(move || { - let mut count = 0; - loop { - for x in response_rx.try_iter() { - count += x; - if count == 6 { - return count; - } - } - request_tx.send(()).unwrap(); - } - }); - - for _ in request_rx.iter() { - if response_tx.send(2).is_err() { - break; - } - } - - assert_eq!(t.join().unwrap(), 6); - } - - #[test] - fn test_recv_into_iter_owned() { - let mut iter = { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - - rx.into_iter() - }; - assert_eq!(iter.next().unwrap(), 1); - assert_eq!(iter.next().unwrap(), 2); - assert_eq!(iter.next().is_none(), true); - } - - #[test] - fn test_recv_into_iter_borrowed() { - let (tx, rx) = channel::<i32>(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - drop(tx); - let mut iter = (&rx).into_iter(); - assert_eq!(iter.next().unwrap(), 1); - assert_eq!(iter.next().unwrap(), 2); - assert_eq!(iter.next().is_none(), true); - } - - #[test] - fn try_recv_states() { - let (tx1, rx1) = channel::<i32>(); - let (tx2, rx2) = channel::<()>(); - let (tx3, rx3) = channel::<()>(); - let _t = thread::spawn(move || { - rx2.recv().unwrap(); - tx1.send(1).unwrap(); - tx3.send(()).unwrap(); - rx2.recv().unwrap(); - drop(tx1); - tx3.send(()).unwrap(); - }); - - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Ok(1)); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected)); - } - - // This bug used to end up in a livelock inside of the Receiver destructor - // because the internal state of the Shared packet was corrupted - #[test] - fn destroy_upgraded_shared_port_when_sender_still_active() { - let (tx, rx) = channel(); - let (tx2, rx2) = channel(); - let _t = thread::spawn(move || { - rx.recv().unwrap(); // wait on a oneshot - drop(rx); // destroy a shared - tx2.send(()).unwrap(); - }); - // make sure the other thread has gone to sleep - for _ in 0..5000 { - thread::yield_now(); - } - - // upgrade to a shared chan and send a message - let t = tx.clone(); - drop(tx); - t.send(()).unwrap(); - - // wait for the child thread to exit before we exit - rx2.recv().unwrap(); - } - - #[test] - fn issue_32114() { - let (tx, _) = channel(); - let _ = tx.send(123); - assert_eq!(tx.send(123), Err(SendError(123))); - } -} - -#[cfg(all(test, not(target_os = "emscripten")))] -mod sync_tests { - use super::*; - use crate::env; - use crate::thread; - use crate::time::Duration; - - pub fn stress_factor() -> usize { - match env::var("RUST_TEST_STRESS") { - Ok(val) => val.parse().unwrap(), - Err(..) => 1, - } - } - - #[test] - fn smoke() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn drop_full() { - let (tx, _rx) = sync_channel::<Box<isize>>(1); - tx.send(box 1).unwrap(); - } - - #[test] - fn smoke_shared() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - let tx = tx.clone(); - tx.send(1).unwrap(); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn recv_timeout() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); - tx.send(1).unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1)); - } - - #[test] - fn smoke_threads() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - tx.send(1).unwrap(); - }); - assert_eq!(rx.recv().unwrap(), 1); - } - - #[test] - fn smoke_port_gone() { - let (tx, rx) = sync_channel::<i32>(0); - drop(rx); - assert!(tx.send(1).is_err()); - } - - #[test] - fn smoke_shared_port_gone2() { - let (tx, rx) = sync_channel::<i32>(0); - drop(rx); - let tx2 = tx.clone(); - drop(tx); - assert!(tx2.send(1).is_err()); - } - - #[test] - fn port_gone_concurrent() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() {} - } - - #[test] - fn port_gone_concurrent_shared() { - let (tx, rx) = sync_channel::<i32>(0); - let tx2 = tx.clone(); - let _t = thread::spawn(move || { - rx.recv().unwrap(); - }); - while tx.send(1).is_ok() && tx2.send(1).is_ok() {} - } - - #[test] - fn smoke_chan_gone() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn smoke_chan_gone_shared() { - let (tx, rx) = sync_channel::<()>(0); - let tx2 = tx.clone(); - drop(tx); - drop(tx2); - assert!(rx.recv().is_err()); - } - - #[test] - fn chan_gone_concurrent() { - let (tx, rx) = sync_channel::<i32>(0); - thread::spawn(move || { - tx.send(1).unwrap(); - tx.send(1).unwrap(); - }); - while rx.recv().is_ok() {} - } - - #[test] - fn stress() { - let (tx, rx) = sync_channel::<i32>(0); - thread::spawn(move || { - for _ in 0..10000 { - tx.send(1).unwrap(); - } - }); - for _ in 0..10000 { - assert_eq!(rx.recv().unwrap(), 1); - } - } - - #[test] - fn stress_recv_timeout_two_threads() { - let (tx, rx) = sync_channel::<i32>(0); - - thread::spawn(move || { - for _ in 0..10000 { - tx.send(1).unwrap(); - } - }); - - let mut recv_count = 0; - loop { - match rx.recv_timeout(Duration::from_millis(1)) { - Ok(v) => { - assert_eq!(v, 1); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, 10000); - } - - #[test] - fn stress_recv_timeout_shared() { - const AMT: u32 = 1000; - const NTHREADS: u32 = 8; - let (tx, rx) = sync_channel::<i32>(0); - let (dtx, drx) = sync_channel::<()>(0); - - thread::spawn(move || { - let mut recv_count = 0; - loop { - match rx.recv_timeout(Duration::from_millis(10)) { - Ok(v) => { - assert_eq!(v, 1); - recv_count += 1; - } - Err(RecvTimeoutError::Timeout) => continue, - Err(RecvTimeoutError::Disconnected) => break, - } - } - - assert_eq!(recv_count, AMT * NTHREADS); - assert!(rx.try_recv().is_err()); - - dtx.send(()).unwrap(); - }); - - for _ in 0..NTHREADS { - let tx = tx.clone(); - thread::spawn(move || { - for _ in 0..AMT { - tx.send(1).unwrap(); - } - }); - } - - drop(tx); - - drx.recv().unwrap(); - } - - #[test] - fn stress_shared() { - const AMT: u32 = 1000; - const NTHREADS: u32 = 8; - let (tx, rx) = sync_channel::<i32>(0); - let (dtx, drx) = sync_channel::<()>(0); - - thread::spawn(move || { - for _ in 0..AMT * NTHREADS { - assert_eq!(rx.recv().unwrap(), 1); - } - match rx.try_recv() { - Ok(..) => panic!(), - _ => {} - } - dtx.send(()).unwrap(); - }); - - for _ in 0..NTHREADS { - let tx = tx.clone(); - thread::spawn(move || { - for _ in 0..AMT { - tx.send(1).unwrap(); - } - }); - } - drop(tx); - drx.recv().unwrap(); - } - - #[test] - fn oneshot_single_thread_close_port_first() { - // Simple test of closing without sending - let (_tx, rx) = sync_channel::<i32>(0); - drop(rx); - } - - #[test] - fn oneshot_single_thread_close_chan_first() { - // Simple test of closing without sending - let (tx, _rx) = sync_channel::<i32>(0); - drop(tx); - } - - #[test] - fn oneshot_single_thread_send_port_close() { - // Testing that the sender cleans up the payload if receiver is closed - let (tx, rx) = sync_channel::<Box<i32>>(0); - drop(rx); - assert!(tx.send(box 0).is_err()); - } - - #[test] - fn oneshot_single_thread_recv_chan_close() { - // Receiving on a closed chan will panic - let res = thread::spawn(move || { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - rx.recv().unwrap(); - }) - .join(); - // What is our res? - assert!(res.is_err()); - } - - #[test] - fn oneshot_single_thread_send_then_recv() { - let (tx, rx) = sync_channel::<Box<i32>>(1); - tx.send(box 10).unwrap(); - assert!(*rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_open() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(tx.try_send(10), Ok(())); - assert!(rx.recv().unwrap() == 10); - } - - #[test] - fn oneshot_single_thread_try_send_closed() { - let (tx, rx) = sync_channel::<i32>(0); - drop(rx); - assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10))); - } - - #[test] - fn oneshot_single_thread_try_send_closed2() { - let (tx, _rx) = sync_channel::<i32>(0); - assert_eq!(tx.try_send(10), Err(TrySendError::Full(10))); - } - - #[test] - fn oneshot_single_thread_try_recv_open() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(10).unwrap(); - assert!(rx.recv() == Ok(10)); - } - - #[test] - fn oneshot_single_thread_try_recv_closed() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert!(rx.recv().is_err()); - } - - #[test] - fn oneshot_single_thread_try_recv_closed_with_data() { - let (tx, rx) = sync_channel::<i32>(1); - tx.send(10).unwrap(); - drop(tx); - assert_eq!(rx.try_recv(), Ok(10)); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - } - - #[test] - fn oneshot_single_thread_peek_data() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - tx.send(10).unwrap(); - assert_eq!(rx.try_recv(), Ok(10)); - } - - #[test] - fn oneshot_single_thread_peek_close() { - let (tx, rx) = sync_channel::<i32>(0); - drop(tx); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); - } - - #[test] - fn oneshot_single_thread_peek_open() { - let (_tx, rx) = sync_channel::<i32>(0); - assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); - } - - #[test] - fn oneshot_multi_task_recv_then_send() { - let (tx, rx) = sync_channel::<Box<i32>>(0); - let _t = thread::spawn(move || { - assert!(*rx.recv().unwrap() == 10); - }); - - tx.send(box 10).unwrap(); - } - - #[test] - fn oneshot_multi_task_recv_then_close() { - let (tx, rx) = sync_channel::<Box<i32>>(0); - let _t = thread::spawn(move || { - drop(tx); - }); - let res = thread::spawn(move || { - assert!(*rx.recv().unwrap() == 10); - }) - .join(); - assert!(res.is_err()); - } - - #[test] - fn oneshot_multi_thread_close_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - drop(rx); - }); - drop(tx); - } - } - - #[test] - fn oneshot_multi_thread_send_close_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - drop(rx); - }); - let _ = thread::spawn(move || { - tx.send(1).unwrap(); - }) - .join(); - } - } - - #[test] - fn oneshot_multi_thread_recv_close_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - let res = thread::spawn(move || { - rx.recv().unwrap(); - }) - .join(); - assert!(res.is_err()); - }); - let _t = thread::spawn(move || { - thread::spawn(move || { - drop(tx); - }); - }); - } - } - - #[test] - fn oneshot_multi_thread_send_recv_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = sync_channel::<Box<i32>>(0); - let _t = thread::spawn(move || { - tx.send(box 10).unwrap(); - }); - assert!(*rx.recv().unwrap() == 10); - } - } - - #[test] - fn stream_send_recv_stress() { - for _ in 0..stress_factor() { - let (tx, rx) = sync_channel::<Box<i32>>(0); - - send(tx, 0); - recv(rx, 0); - - fn send(tx: SyncSender<Box<i32>>, i: i32) { - if i == 10 { - return; - } - - thread::spawn(move || { - tx.send(box i).unwrap(); - send(tx, i + 1); - }); - } - - fn recv(rx: Receiver<Box<i32>>, i: i32) { - if i == 10 { - return; - } - - thread::spawn(move || { - assert!(*rx.recv().unwrap() == i); - recv(rx, i + 1); - }); - } - } - } - - #[test] - fn recv_a_lot() { - // Regression test that we don't run out of stack in scheduler context - let (tx, rx) = sync_channel(10000); - for _ in 0..10000 { - tx.send(()).unwrap(); - } - for _ in 0..10000 { - rx.recv().unwrap(); - } - } - - #[test] - fn shared_chan_stress() { - let (tx, rx) = sync_channel(0); - let total = stress_factor() + 100; - for _ in 0..total { - let tx = tx.clone(); - thread::spawn(move || { - tx.send(()).unwrap(); - }); - } - - for _ in 0..total { - rx.recv().unwrap(); - } - } - - #[test] - fn test_nested_recv_iter() { - let (tx, rx) = sync_channel::<i32>(0); - let (total_tx, total_rx) = sync_channel::<i32>(0); - - let _t = thread::spawn(move || { - let mut acc = 0; - for x in rx.iter() { - acc += x; - } - total_tx.send(acc).unwrap(); - }); - - tx.send(3).unwrap(); - tx.send(1).unwrap(); - tx.send(2).unwrap(); - drop(tx); - assert_eq!(total_rx.recv().unwrap(), 6); - } - - #[test] - fn test_recv_iter_break() { - let (tx, rx) = sync_channel::<i32>(0); - let (count_tx, count_rx) = sync_channel(0); - - let _t = thread::spawn(move || { - let mut count = 0; - for x in rx.iter() { - if count >= 3 { - break; - } else { - count += x; - } - } - count_tx.send(count).unwrap(); - }); - - tx.send(2).unwrap(); - tx.send(2).unwrap(); - tx.send(2).unwrap(); - let _ = tx.try_send(2); - drop(tx); - assert_eq!(count_rx.recv().unwrap(), 4); - } - - #[test] - fn try_recv_states() { - let (tx1, rx1) = sync_channel::<i32>(1); - let (tx2, rx2) = sync_channel::<()>(1); - let (tx3, rx3) = sync_channel::<()>(1); - let _t = thread::spawn(move || { - rx2.recv().unwrap(); - tx1.send(1).unwrap(); - tx3.send(()).unwrap(); - rx2.recv().unwrap(); - drop(tx1); - tx3.send(()).unwrap(); - }); - - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Ok(1)); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); - tx2.send(()).unwrap(); - rx3.recv().unwrap(); - assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected)); - } - - // This bug used to end up in a livelock inside of the Receiver destructor - // because the internal state of the Shared packet was corrupted - #[test] - fn destroy_upgraded_shared_port_when_sender_still_active() { - let (tx, rx) = sync_channel::<()>(0); - let (tx2, rx2) = sync_channel::<()>(0); - let _t = thread::spawn(move || { - rx.recv().unwrap(); // wait on a oneshot - drop(rx); // destroy a shared - tx2.send(()).unwrap(); - }); - // make sure the other thread has gone to sleep - for _ in 0..5000 { - thread::yield_now(); - } - - // upgrade to a shared chan and send a message - let t = tx.clone(); - drop(tx); - t.send(()).unwrap(); - - // wait for the child thread to exit before we exit - rx2.recv().unwrap(); - } - - #[test] - fn send1() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - rx.recv().unwrap(); - }); - assert_eq!(tx.send(1), Ok(())); - } - - #[test] - fn send2() { - let (tx, rx) = sync_channel::<i32>(0); - let _t = thread::spawn(move || { - drop(rx); - }); - assert!(tx.send(1).is_err()); - } - - #[test] - fn send3() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(tx.send(1), Ok(())); - let _t = thread::spawn(move || { - drop(rx); - }); - assert!(tx.send(1).is_err()); - } - - #[test] - fn send4() { - let (tx, rx) = sync_channel::<i32>(0); - let tx2 = tx.clone(); - let (done, donerx) = channel(); - let done2 = done.clone(); - let _t = thread::spawn(move || { - assert!(tx.send(1).is_err()); - done.send(()).unwrap(); - }); - let _t = thread::spawn(move || { - assert!(tx2.send(2).is_err()); - done2.send(()).unwrap(); - }); - drop(rx); - donerx.recv().unwrap(); - donerx.recv().unwrap(); - } - - #[test] - fn try_send1() { - let (tx, _rx) = sync_channel::<i32>(0); - assert_eq!(tx.try_send(1), Err(TrySendError::Full(1))); - } - - #[test] - fn try_send2() { - let (tx, _rx) = sync_channel::<i32>(1); - assert_eq!(tx.try_send(1), Ok(())); - assert_eq!(tx.try_send(1), Err(TrySendError::Full(1))); - } - - #[test] - fn try_send3() { - let (tx, rx) = sync_channel::<i32>(1); - assert_eq!(tx.try_send(1), Ok(())); - drop(rx); - assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1))); - } - - #[test] - fn issue_15761() { - fn repro() { - let (tx1, rx1) = sync_channel::<()>(3); - let (tx2, rx2) = sync_channel::<()>(3); - - let _t = thread::spawn(move || { - rx1.recv().unwrap(); - tx2.try_send(()).unwrap(); - }); - - tx1.try_send(()).unwrap(); - rx2.recv().unwrap(); - } - - for _ in 0..100 { - repro() - } - } -} diff --git a/library/std/src/sync/mpsc/mpsc_queue.rs b/library/std/src/sync/mpsc/mpsc_queue.rs index 6e7a7be4430..42bc639dc25 100644 --- a/library/std/src/sync/mpsc/mpsc_queue.rs +++ b/library/std/src/sync/mpsc/mpsc_queue.rs @@ -11,6 +11,9 @@ // http://www.1024cores.net/home/lock-free-algorithms // /queues/non-intrusive-mpsc-node-based-queue +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + pub use self::PopResult::*; use core::cell::UnsafeCell; @@ -112,54 +115,3 @@ impl<T> Drop for Queue<T> { } } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use super::{Data, Empty, Inconsistent, Queue}; - use crate::sync::mpsc::channel; - use crate::sync::Arc; - use crate::thread; - - #[test] - fn test_full() { - let q: Queue<Box<_>> = Queue::new(); - q.push(box 1); - q.push(box 2); - } - - #[test] - fn test() { - let nthreads = 8; - let nmsgs = 1000; - let q = Queue::new(); - match q.pop() { - Empty => {} - Inconsistent | Data(..) => panic!(), - } - let (tx, rx) = channel(); - let q = Arc::new(q); - - for _ in 0..nthreads { - let tx = tx.clone(); - let q = q.clone(); - thread::spawn(move || { - for i in 0..nmsgs { - q.push(i); - } - tx.send(()).unwrap(); - }); - } - - let mut i = 0; - while i < nthreads * nmsgs { - match q.pop() { - Empty | Inconsistent => {} - Data(_) => i += 1, - } - } - drop(tx); - for _ in 0..nthreads { - rx.recv().unwrap(); - } - } -} diff --git a/library/std/src/sync/mpsc/mpsc_queue/tests.rs b/library/std/src/sync/mpsc/mpsc_queue/tests.rs new file mode 100644 index 00000000000..348b83424b0 --- /dev/null +++ b/library/std/src/sync/mpsc/mpsc_queue/tests.rs @@ -0,0 +1,47 @@ +use super::{Data, Empty, Inconsistent, Queue}; +use crate::sync::mpsc::channel; +use crate::sync::Arc; +use crate::thread; + +#[test] +fn test_full() { + let q: Queue<Box<_>> = Queue::new(); + q.push(box 1); + q.push(box 2); +} + +#[test] +fn test() { + let nthreads = 8; + let nmsgs = 1000; + let q = Queue::new(); + match q.pop() { + Empty => {} + Inconsistent | Data(..) => panic!(), + } + let (tx, rx) = channel(); + let q = Arc::new(q); + + for _ in 0..nthreads { + let tx = tx.clone(); + let q = q.clone(); + thread::spawn(move || { + for i in 0..nmsgs { + q.push(i); + } + tx.send(()).unwrap(); + }); + } + + let mut i = 0; + while i < nthreads * nmsgs { + match q.pop() { + Empty | Inconsistent => {} + Data(_) => i += 1, + } + } + drop(tx); + for _ in 0..nthreads { + rx.recv().unwrap(); + } +} diff --git a/library/std/src/sync/mpsc/spsc_queue.rs b/library/std/src/sync/mpsc/spsc_queue.rs index 0274268f69f..9bf99f193ca 100644 --- a/library/std/src/sync/mpsc/spsc_queue.rs +++ b/library/std/src/sync/mpsc/spsc_queue.rs @@ -6,6 +6,9 @@ // http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use core::cell::UnsafeCell; use core::ptr; @@ -231,108 +234,3 @@ impl<T, ProducerAddition, ConsumerAddition> Drop for Queue<T, ProducerAddition, } } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use super::Queue; - use crate::sync::mpsc::channel; - use crate::sync::Arc; - use crate::thread; - - #[test] - fn smoke() { - unsafe { - let queue = Queue::with_additions(0, (), ()); - queue.push(1); - queue.push(2); - assert_eq!(queue.pop(), Some(1)); - assert_eq!(queue.pop(), Some(2)); - assert_eq!(queue.pop(), None); - queue.push(3); - queue.push(4); - assert_eq!(queue.pop(), Some(3)); - assert_eq!(queue.pop(), Some(4)); - assert_eq!(queue.pop(), None); - } - } - - #[test] - fn peek() { - unsafe { - let queue = Queue::with_additions(0, (), ()); - queue.push(vec![1]); - - // Ensure the borrowchecker works - match queue.peek() { - Some(vec) => { - assert_eq!(&*vec, &[1]); - } - None => unreachable!(), - } - - match queue.pop() { - Some(vec) => { - assert_eq!(&*vec, &[1]); - } - None => unreachable!(), - } - } - } - - #[test] - fn drop_full() { - unsafe { - let q: Queue<Box<_>> = Queue::with_additions(0, (), ()); - q.push(box 1); - q.push(box 2); - } - } - - #[test] - fn smoke_bound() { - unsafe { - let q = Queue::with_additions(0, (), ()); - q.push(1); - q.push(2); - assert_eq!(q.pop(), Some(1)); - assert_eq!(q.pop(), Some(2)); - assert_eq!(q.pop(), None); - q.push(3); - q.push(4); - assert_eq!(q.pop(), Some(3)); - assert_eq!(q.pop(), Some(4)); - assert_eq!(q.pop(), None); - } - } - - #[test] - fn stress() { - unsafe { - stress_bound(0); - stress_bound(1); - } - - unsafe fn stress_bound(bound: usize) { - let q = Arc::new(Queue::with_additions(bound, (), ())); - - let (tx, rx) = channel(); - let q2 = q.clone(); - let _t = thread::spawn(move || { - for _ in 0..100000 { - loop { - match q2.pop() { - Some(1) => break, - Some(_) => panic!(), - None => {} - } - } - } - tx.send(()).unwrap(); - }); - for _ in 0..100000 { - q.push(1); - } - rx.recv().unwrap(); - } - } -} diff --git a/library/std/src/sync/mpsc/spsc_queue/tests.rs b/library/std/src/sync/mpsc/spsc_queue/tests.rs new file mode 100644 index 00000000000..e4fd15cbbde --- /dev/null +++ b/library/std/src/sync/mpsc/spsc_queue/tests.rs @@ -0,0 +1,101 @@ +use super::Queue; +use crate::sync::mpsc::channel; +use crate::sync::Arc; +use crate::thread; + +#[test] +fn smoke() { + unsafe { + let queue = Queue::with_additions(0, (), ()); + queue.push(1); + queue.push(2); + assert_eq!(queue.pop(), Some(1)); + assert_eq!(queue.pop(), Some(2)); + assert_eq!(queue.pop(), None); + queue.push(3); + queue.push(4); + assert_eq!(queue.pop(), Some(3)); + assert_eq!(queue.pop(), Some(4)); + assert_eq!(queue.pop(), None); + } +} + +#[test] +fn peek() { + unsafe { + let queue = Queue::with_additions(0, (), ()); + queue.push(vec![1]); + + // Ensure the borrowchecker works + match queue.peek() { + Some(vec) => { + assert_eq!(&*vec, &[1]); + } + None => unreachable!(), + } + + match queue.pop() { + Some(vec) => { + assert_eq!(&*vec, &[1]); + } + None => unreachable!(), + } + } +} + +#[test] +fn drop_full() { + unsafe { + let q: Queue<Box<_>> = Queue::with_additions(0, (), ()); + q.push(box 1); + q.push(box 2); + } +} + +#[test] +fn smoke_bound() { + unsafe { + let q = Queue::with_additions(0, (), ()); + q.push(1); + q.push(2); + assert_eq!(q.pop(), Some(1)); + assert_eq!(q.pop(), Some(2)); + assert_eq!(q.pop(), None); + q.push(3); + q.push(4); + assert_eq!(q.pop(), Some(3)); + assert_eq!(q.pop(), Some(4)); + assert_eq!(q.pop(), None); + } +} + +#[test] +fn stress() { + unsafe { + stress_bound(0); + stress_bound(1); + } + + unsafe fn stress_bound(bound: usize) { + let q = Arc::new(Queue::with_additions(bound, (), ())); + + let (tx, rx) = channel(); + let q2 = q.clone(); + let _t = thread::spawn(move || { + for _ in 0..100000 { + loop { + match q2.pop() { + Some(1) => break, + Some(_) => panic!(), + None => {} + } + } + } + tx.send(()).unwrap(); + }); + for _ in 0..100000 { + q.push(1); + } + rx.recv().unwrap(); + } +} diff --git a/library/std/src/sync/mpsc/sync_tests.rs b/library/std/src/sync/mpsc/sync_tests.rs new file mode 100644 index 00000000000..0052a38f7bb --- /dev/null +++ b/library/std/src/sync/mpsc/sync_tests.rs @@ -0,0 +1,647 @@ +use super::*; +use crate::env; +use crate::thread; +use crate::time::Duration; + +pub fn stress_factor() -> usize { + match env::var("RUST_TEST_STRESS") { + Ok(val) => val.parse().unwrap(), + Err(..) => 1, + } +} + +#[test] +fn smoke() { + let (tx, rx) = sync_channel::<i32>(1); + tx.send(1).unwrap(); + assert_eq!(rx.recv().unwrap(), 1); +} + +#[test] +fn drop_full() { + let (tx, _rx) = sync_channel::<Box<isize>>(1); + tx.send(box 1).unwrap(); +} + +#[test] +fn smoke_shared() { + let (tx, rx) = sync_channel::<i32>(1); + tx.send(1).unwrap(); + assert_eq!(rx.recv().unwrap(), 1); + let tx = tx.clone(); + tx.send(1).unwrap(); + assert_eq!(rx.recv().unwrap(), 1); +} + +#[test] +fn recv_timeout() { + let (tx, rx) = sync_channel::<i32>(1); + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); + tx.send(1).unwrap(); + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1)); +} + +#[test] +fn smoke_threads() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + tx.send(1).unwrap(); + }); + assert_eq!(rx.recv().unwrap(), 1); +} + +#[test] +fn smoke_port_gone() { + let (tx, rx) = sync_channel::<i32>(0); + drop(rx); + assert!(tx.send(1).is_err()); +} + +#[test] +fn smoke_shared_port_gone2() { + let (tx, rx) = sync_channel::<i32>(0); + drop(rx); + let tx2 = tx.clone(); + drop(tx); + assert!(tx2.send(1).is_err()); +} + +#[test] +fn port_gone_concurrent() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + rx.recv().unwrap(); + }); + while tx.send(1).is_ok() {} +} + +#[test] +fn port_gone_concurrent_shared() { + let (tx, rx) = sync_channel::<i32>(0); + let tx2 = tx.clone(); + let _t = thread::spawn(move || { + rx.recv().unwrap(); + }); + while tx.send(1).is_ok() && tx2.send(1).is_ok() {} +} + +#[test] +fn smoke_chan_gone() { + let (tx, rx) = sync_channel::<i32>(0); + drop(tx); + assert!(rx.recv().is_err()); +} + +#[test] +fn smoke_chan_gone_shared() { + let (tx, rx) = sync_channel::<()>(0); + let tx2 = tx.clone(); + drop(tx); + drop(tx2); + assert!(rx.recv().is_err()); +} + +#[test] +fn chan_gone_concurrent() { + let (tx, rx) = sync_channel::<i32>(0); + thread::spawn(move || { + tx.send(1).unwrap(); + tx.send(1).unwrap(); + }); + while rx.recv().is_ok() {} +} + +#[test] +fn stress() { + let (tx, rx) = sync_channel::<i32>(0); + thread::spawn(move || { + for _ in 0..10000 { + tx.send(1).unwrap(); + } + }); + for _ in 0..10000 { + assert_eq!(rx.recv().unwrap(), 1); + } +} + +#[test] +fn stress_recv_timeout_two_threads() { + let (tx, rx) = sync_channel::<i32>(0); + + thread::spawn(move || { + for _ in 0..10000 { + tx.send(1).unwrap(); + } + }); + + let mut recv_count = 0; + loop { + match rx.recv_timeout(Duration::from_millis(1)) { + Ok(v) => { + assert_eq!(v, 1); + recv_count += 1; + } + Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Disconnected) => break, + } + } + + assert_eq!(recv_count, 10000); +} + +#[test] +fn stress_recv_timeout_shared() { + const AMT: u32 = 1000; + const NTHREADS: u32 = 8; + let (tx, rx) = sync_channel::<i32>(0); + let (dtx, drx) = sync_channel::<()>(0); + + thread::spawn(move || { + let mut recv_count = 0; + loop { + match rx.recv_timeout(Duration::from_millis(10)) { + Ok(v) => { + assert_eq!(v, 1); + recv_count += 1; + } + Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Disconnected) => break, + } + } + + assert_eq!(recv_count, AMT * NTHREADS); + assert!(rx.try_recv().is_err()); + + dtx.send(()).unwrap(); + }); + + for _ in 0..NTHREADS { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..AMT { + tx.send(1).unwrap(); + } + }); + } + + drop(tx); + + drx.recv().unwrap(); +} + +#[test] +fn stress_shared() { + const AMT: u32 = 1000; + const NTHREADS: u32 = 8; + let (tx, rx) = sync_channel::<i32>(0); + let (dtx, drx) = sync_channel::<()>(0); + + thread::spawn(move || { + for _ in 0..AMT * NTHREADS { + assert_eq!(rx.recv().unwrap(), 1); + } + match rx.try_recv() { + Ok(..) => panic!(), + _ => {} + } + dtx.send(()).unwrap(); + }); + + for _ in 0..NTHREADS { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..AMT { + tx.send(1).unwrap(); + } + }); + } + drop(tx); + drx.recv().unwrap(); +} + +#[test] +fn oneshot_single_thread_close_port_first() { + // Simple test of closing without sending + let (_tx, rx) = sync_channel::<i32>(0); + drop(rx); +} + +#[test] +fn oneshot_single_thread_close_chan_first() { + // Simple test of closing without sending + let (tx, _rx) = sync_channel::<i32>(0); + drop(tx); +} + +#[test] +fn oneshot_single_thread_send_port_close() { + // Testing that the sender cleans up the payload if receiver is closed + let (tx, rx) = sync_channel::<Box<i32>>(0); + drop(rx); + assert!(tx.send(box 0).is_err()); +} + +#[test] +fn oneshot_single_thread_recv_chan_close() { + // Receiving on a closed chan will panic + let res = thread::spawn(move || { + let (tx, rx) = sync_channel::<i32>(0); + drop(tx); + rx.recv().unwrap(); + }) + .join(); + // What is our res? + assert!(res.is_err()); +} + +#[test] +fn oneshot_single_thread_send_then_recv() { + let (tx, rx) = sync_channel::<Box<i32>>(1); + tx.send(box 10).unwrap(); + assert!(*rx.recv().unwrap() == 10); +} + +#[test] +fn oneshot_single_thread_try_send_open() { + let (tx, rx) = sync_channel::<i32>(1); + assert_eq!(tx.try_send(10), Ok(())); + assert!(rx.recv().unwrap() == 10); +} + +#[test] +fn oneshot_single_thread_try_send_closed() { + let (tx, rx) = sync_channel::<i32>(0); + drop(rx); + assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10))); +} + +#[test] +fn oneshot_single_thread_try_send_closed2() { + let (tx, _rx) = sync_channel::<i32>(0); + assert_eq!(tx.try_send(10), Err(TrySendError::Full(10))); +} + +#[test] +fn oneshot_single_thread_try_recv_open() { + let (tx, rx) = sync_channel::<i32>(1); + tx.send(10).unwrap(); + assert!(rx.recv() == Ok(10)); +} + +#[test] +fn oneshot_single_thread_try_recv_closed() { + let (tx, rx) = sync_channel::<i32>(0); + drop(tx); + assert!(rx.recv().is_err()); +} + +#[test] +fn oneshot_single_thread_try_recv_closed_with_data() { + let (tx, rx) = sync_channel::<i32>(1); + tx.send(10).unwrap(); + drop(tx); + assert_eq!(rx.try_recv(), Ok(10)); + assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); +} + +#[test] +fn oneshot_single_thread_peek_data() { + let (tx, rx) = sync_channel::<i32>(1); + assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); + tx.send(10).unwrap(); + assert_eq!(rx.try_recv(), Ok(10)); +} + +#[test] +fn oneshot_single_thread_peek_close() { + let (tx, rx) = sync_channel::<i32>(0); + drop(tx); + assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); + assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); +} + +#[test] +fn oneshot_single_thread_peek_open() { + let (_tx, rx) = sync_channel::<i32>(0); + assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); +} + +#[test] +fn oneshot_multi_task_recv_then_send() { + let (tx, rx) = sync_channel::<Box<i32>>(0); + let _t = thread::spawn(move || { + assert!(*rx.recv().unwrap() == 10); + }); + + tx.send(box 10).unwrap(); +} + +#[test] +fn oneshot_multi_task_recv_then_close() { + let (tx, rx) = sync_channel::<Box<i32>>(0); + let _t = thread::spawn(move || { + drop(tx); + }); + let res = thread::spawn(move || { + assert!(*rx.recv().unwrap() == 10); + }) + .join(); + assert!(res.is_err()); +} + +#[test] +fn oneshot_multi_thread_close_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + drop(rx); + }); + drop(tx); + } +} + +#[test] +fn oneshot_multi_thread_send_close_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + drop(rx); + }); + let _ = thread::spawn(move || { + tx.send(1).unwrap(); + }) + .join(); + } +} + +#[test] +fn oneshot_multi_thread_recv_close_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + let res = thread::spawn(move || { + rx.recv().unwrap(); + }) + .join(); + assert!(res.is_err()); + }); + let _t = thread::spawn(move || { + thread::spawn(move || { + drop(tx); + }); + }); + } +} + +#[test] +fn oneshot_multi_thread_send_recv_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = sync_channel::<Box<i32>>(0); + let _t = thread::spawn(move || { + tx.send(box 10).unwrap(); + }); + assert!(*rx.recv().unwrap() == 10); + } +} + +#[test] +fn stream_send_recv_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = sync_channel::<Box<i32>>(0); + + send(tx, 0); + recv(rx, 0); + + fn send(tx: SyncSender<Box<i32>>, i: i32) { + if i == 10 { + return; + } + + thread::spawn(move || { + tx.send(box i).unwrap(); + send(tx, i + 1); + }); + } + + fn recv(rx: Receiver<Box<i32>>, i: i32) { + if i == 10 { + return; + } + + thread::spawn(move || { + assert!(*rx.recv().unwrap() == i); + recv(rx, i + 1); + }); + } + } +} + +#[test] +fn recv_a_lot() { + // Regression test that we don't run out of stack in scheduler context + let (tx, rx) = sync_channel(10000); + for _ in 0..10000 { + tx.send(()).unwrap(); + } + for _ in 0..10000 { + rx.recv().unwrap(); + } +} + +#[test] +fn shared_chan_stress() { + let (tx, rx) = sync_channel(0); + let total = stress_factor() + 100; + for _ in 0..total { + let tx = tx.clone(); + thread::spawn(move || { + tx.send(()).unwrap(); + }); + } + + for _ in 0..total { + rx.recv().unwrap(); + } +} + +#[test] +fn test_nested_recv_iter() { + let (tx, rx) = sync_channel::<i32>(0); + let (total_tx, total_rx) = sync_channel::<i32>(0); + + let _t = thread::spawn(move || { + let mut acc = 0; + for x in rx.iter() { + acc += x; + } + total_tx.send(acc).unwrap(); + }); + + tx.send(3).unwrap(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + drop(tx); + assert_eq!(total_rx.recv().unwrap(), 6); +} + +#[test] +fn test_recv_iter_break() { + let (tx, rx) = sync_channel::<i32>(0); + let (count_tx, count_rx) = sync_channel(0); + + let _t = thread::spawn(move || { + let mut count = 0; + for x in rx.iter() { + if count >= 3 { + break; + } else { + count += x; + } + } + count_tx.send(count).unwrap(); + }); + + tx.send(2).unwrap(); + tx.send(2).unwrap(); + tx.send(2).unwrap(); + let _ = tx.try_send(2); + drop(tx); + assert_eq!(count_rx.recv().unwrap(), 4); +} + +#[test] +fn try_recv_states() { + let (tx1, rx1) = sync_channel::<i32>(1); + let (tx2, rx2) = sync_channel::<()>(1); + let (tx3, rx3) = sync_channel::<()>(1); + let _t = thread::spawn(move || { + rx2.recv().unwrap(); + tx1.send(1).unwrap(); + tx3.send(()).unwrap(); + rx2.recv().unwrap(); + drop(tx1); + tx3.send(()).unwrap(); + }); + + assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); + tx2.send(()).unwrap(); + rx3.recv().unwrap(); + assert_eq!(rx1.try_recv(), Ok(1)); + assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); + tx2.send(()).unwrap(); + rx3.recv().unwrap(); + assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected)); +} + +// This bug used to end up in a livelock inside of the Receiver destructor +// because the internal state of the Shared packet was corrupted +#[test] +fn destroy_upgraded_shared_port_when_sender_still_active() { + let (tx, rx) = sync_channel::<()>(0); + let (tx2, rx2) = sync_channel::<()>(0); + let _t = thread::spawn(move || { + rx.recv().unwrap(); // wait on a oneshot + drop(rx); // destroy a shared + tx2.send(()).unwrap(); + }); + // make sure the other thread has gone to sleep + for _ in 0..5000 { + thread::yield_now(); + } + + // upgrade to a shared chan and send a message + let t = tx.clone(); + drop(tx); + t.send(()).unwrap(); + + // wait for the child thread to exit before we exit + rx2.recv().unwrap(); +} + +#[test] +fn send1() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + rx.recv().unwrap(); + }); + assert_eq!(tx.send(1), Ok(())); +} + +#[test] +fn send2() { + let (tx, rx) = sync_channel::<i32>(0); + let _t = thread::spawn(move || { + drop(rx); + }); + assert!(tx.send(1).is_err()); +} + +#[test] +fn send3() { + let (tx, rx) = sync_channel::<i32>(1); + assert_eq!(tx.send(1), Ok(())); + let _t = thread::spawn(move || { + drop(rx); + }); + assert!(tx.send(1).is_err()); +} + +#[test] +fn send4() { + let (tx, rx) = sync_channel::<i32>(0); + let tx2 = tx.clone(); + let (done, donerx) = channel(); + let done2 = done.clone(); + let _t = thread::spawn(move || { + assert!(tx.send(1).is_err()); + done.send(()).unwrap(); + }); + let _t = thread::spawn(move || { + assert!(tx2.send(2).is_err()); + done2.send(()).unwrap(); + }); + drop(rx); + donerx.recv().unwrap(); + donerx.recv().unwrap(); +} + +#[test] +fn try_send1() { + let (tx, _rx) = sync_channel::<i32>(0); + assert_eq!(tx.try_send(1), Err(TrySendError::Full(1))); +} + +#[test] +fn try_send2() { + let (tx, _rx) = sync_channel::<i32>(1); + assert_eq!(tx.try_send(1), Ok(())); + assert_eq!(tx.try_send(1), Err(TrySendError::Full(1))); +} + +#[test] +fn try_send3() { + let (tx, rx) = sync_channel::<i32>(1); + assert_eq!(tx.try_send(1), Ok(())); + drop(rx); + assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1))); +} + +#[test] +fn issue_15761() { + fn repro() { + let (tx1, rx1) = sync_channel::<()>(3); + let (tx2, rx2) = sync_channel::<()>(3); + + let _t = thread::spawn(move || { + rx1.recv().unwrap(); + tx2.try_send(()).unwrap(); + }); + + tx1.try_send(()).unwrap(); + rx2.recv().unwrap(); + } + + for _ in 0..100 { + repro() + } +} diff --git a/library/std/src/sync/mpsc/tests.rs b/library/std/src/sync/mpsc/tests.rs new file mode 100644 index 00000000000..184ce193cbe --- /dev/null +++ b/library/std/src/sync/mpsc/tests.rs @@ -0,0 +1,706 @@ +use super::*; +use crate::env; +use crate::thread; +use crate::time::{Duration, Instant}; + +pub fn stress_factor() -> usize { + match env::var("RUST_TEST_STRESS") { + Ok(val) => val.parse().unwrap(), + Err(..) => 1, + } +} + +#[test] +fn smoke() { + let (tx, rx) = channel::<i32>(); + tx.send(1).unwrap(); + assert_eq!(rx.recv().unwrap(), 1); +} + +#[test] +fn drop_full() { + let (tx, _rx) = channel::<Box<isize>>(); + tx.send(box 1).unwrap(); +} + +#[test] +fn drop_full_shared() { + let (tx, _rx) = channel::<Box<isize>>(); + drop(tx.clone()); + drop(tx.clone()); + tx.send(box 1).unwrap(); +} + +#[test] +fn smoke_shared() { + let (tx, rx) = channel::<i32>(); + tx.send(1).unwrap(); + assert_eq!(rx.recv().unwrap(), 1); + let tx = tx.clone(); + tx.send(1).unwrap(); + assert_eq!(rx.recv().unwrap(), 1); +} + +#[test] +fn smoke_threads() { + let (tx, rx) = channel::<i32>(); + let _t = thread::spawn(move || { + tx.send(1).unwrap(); + }); + assert_eq!(rx.recv().unwrap(), 1); +} + +#[test] +fn smoke_port_gone() { + let (tx, rx) = channel::<i32>(); + drop(rx); + assert!(tx.send(1).is_err()); +} + +#[test] +fn smoke_shared_port_gone() { + let (tx, rx) = channel::<i32>(); + drop(rx); + assert!(tx.send(1).is_err()) +} + +#[test] +fn smoke_shared_port_gone2() { + let (tx, rx) = channel::<i32>(); + drop(rx); + let tx2 = tx.clone(); + drop(tx); + assert!(tx2.send(1).is_err()); +} + +#[test] +fn port_gone_concurrent() { + let (tx, rx) = channel::<i32>(); + let _t = thread::spawn(move || { + rx.recv().unwrap(); + }); + while tx.send(1).is_ok() {} +} + +#[test] +fn port_gone_concurrent_shared() { + let (tx, rx) = channel::<i32>(); + let tx2 = tx.clone(); + let _t = thread::spawn(move || { + rx.recv().unwrap(); + }); + while tx.send(1).is_ok() && tx2.send(1).is_ok() {} +} + +#[test] +fn smoke_chan_gone() { + let (tx, rx) = channel::<i32>(); + drop(tx); + assert!(rx.recv().is_err()); +} + +#[test] +fn smoke_chan_gone_shared() { + let (tx, rx) = channel::<()>(); + let tx2 = tx.clone(); + drop(tx); + drop(tx2); + assert!(rx.recv().is_err()); +} + +#[test] +fn chan_gone_concurrent() { + let (tx, rx) = channel::<i32>(); + let _t = thread::spawn(move || { + tx.send(1).unwrap(); + tx.send(1).unwrap(); + }); + while rx.recv().is_ok() {} +} + +#[test] +fn stress() { + let (tx, rx) = channel::<i32>(); + let t = thread::spawn(move || { + for _ in 0..10000 { + tx.send(1).unwrap(); + } + }); + for _ in 0..10000 { + assert_eq!(rx.recv().unwrap(), 1); + } + t.join().ok().expect("thread panicked"); +} + +#[test] +fn stress_shared() { + const AMT: u32 = 10000; + const NTHREADS: u32 = 8; + let (tx, rx) = channel::<i32>(); + + let t = thread::spawn(move || { + for _ in 0..AMT * NTHREADS { + assert_eq!(rx.recv().unwrap(), 1); + } + match rx.try_recv() { + Ok(..) => panic!(), + _ => {} + } + }); + + for _ in 0..NTHREADS { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..AMT { + tx.send(1).unwrap(); + } + }); + } + drop(tx); + t.join().ok().expect("thread panicked"); +} + +#[test] +fn send_from_outside_runtime() { + let (tx1, rx1) = channel::<()>(); + let (tx2, rx2) = channel::<i32>(); + let t1 = thread::spawn(move || { + tx1.send(()).unwrap(); + for _ in 0..40 { + assert_eq!(rx2.recv().unwrap(), 1); + } + }); + rx1.recv().unwrap(); + let t2 = thread::spawn(move || { + for _ in 0..40 { + tx2.send(1).unwrap(); + } + }); + t1.join().ok().expect("thread panicked"); + t2.join().ok().expect("thread panicked"); +} + +#[test] +fn recv_from_outside_runtime() { + let (tx, rx) = channel::<i32>(); + let t = thread::spawn(move || { + for _ in 0..40 { + assert_eq!(rx.recv().unwrap(), 1); + } + }); + for _ in 0..40 { + tx.send(1).unwrap(); + } + t.join().ok().expect("thread panicked"); +} + +#[test] +fn no_runtime() { + let (tx1, rx1) = channel::<i32>(); + let (tx2, rx2) = channel::<i32>(); + let t1 = thread::spawn(move || { + assert_eq!(rx1.recv().unwrap(), 1); + tx2.send(2).unwrap(); + }); + let t2 = thread::spawn(move || { + tx1.send(1).unwrap(); + assert_eq!(rx2.recv().unwrap(), 2); + }); + t1.join().ok().expect("thread panicked"); + t2.join().ok().expect("thread panicked"); +} + +#[test] +fn oneshot_single_thread_close_port_first() { + // Simple test of closing without sending + let (_tx, rx) = channel::<i32>(); + drop(rx); +} + +#[test] +fn oneshot_single_thread_close_chan_first() { + // Simple test of closing without sending + let (tx, _rx) = channel::<i32>(); + drop(tx); +} + +#[test] +fn oneshot_single_thread_send_port_close() { + // Testing that the sender cleans up the payload if receiver is closed + let (tx, rx) = channel::<Box<i32>>(); + drop(rx); + assert!(tx.send(box 0).is_err()); +} + +#[test] +fn oneshot_single_thread_recv_chan_close() { + // Receiving on a closed chan will panic + let res = thread::spawn(move || { + let (tx, rx) = channel::<i32>(); + drop(tx); + rx.recv().unwrap(); + }) + .join(); + // What is our res? + assert!(res.is_err()); +} + +#[test] +fn oneshot_single_thread_send_then_recv() { + let (tx, rx) = channel::<Box<i32>>(); + tx.send(box 10).unwrap(); + assert!(*rx.recv().unwrap() == 10); +} + +#[test] +fn oneshot_single_thread_try_send_open() { + let (tx, rx) = channel::<i32>(); + assert!(tx.send(10).is_ok()); + assert!(rx.recv().unwrap() == 10); +} + +#[test] +fn oneshot_single_thread_try_send_closed() { + let (tx, rx) = channel::<i32>(); + drop(rx); + assert!(tx.send(10).is_err()); +} + +#[test] +fn oneshot_single_thread_try_recv_open() { + let (tx, rx) = channel::<i32>(); + tx.send(10).unwrap(); + assert!(rx.recv() == Ok(10)); +} + +#[test] +fn oneshot_single_thread_try_recv_closed() { + let (tx, rx) = channel::<i32>(); + drop(tx); + assert!(rx.recv().is_err()); +} + +#[test] +fn oneshot_single_thread_peek_data() { + let (tx, rx) = channel::<i32>(); + assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); + tx.send(10).unwrap(); + assert_eq!(rx.try_recv(), Ok(10)); +} + +#[test] +fn oneshot_single_thread_peek_close() { + let (tx, rx) = channel::<i32>(); + drop(tx); + assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); + assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected)); +} + +#[test] +fn oneshot_single_thread_peek_open() { + let (_tx, rx) = channel::<i32>(); + assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); +} + +#[test] +fn oneshot_multi_task_recv_then_send() { + let (tx, rx) = channel::<Box<i32>>(); + let _t = thread::spawn(move || { + assert!(*rx.recv().unwrap() == 10); + }); + + tx.send(box 10).unwrap(); +} + +#[test] +fn oneshot_multi_task_recv_then_close() { + let (tx, rx) = channel::<Box<i32>>(); + let _t = thread::spawn(move || { + drop(tx); + }); + let res = thread::spawn(move || { + assert!(*rx.recv().unwrap() == 10); + }) + .join(); + assert!(res.is_err()); +} + +#[test] +fn oneshot_multi_thread_close_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = channel::<i32>(); + let _t = thread::spawn(move || { + drop(rx); + }); + drop(tx); + } +} + +#[test] +fn oneshot_multi_thread_send_close_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = channel::<i32>(); + let _t = thread::spawn(move || { + drop(rx); + }); + let _ = thread::spawn(move || { + tx.send(1).unwrap(); + }) + .join(); + } +} + +#[test] +fn oneshot_multi_thread_recv_close_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = channel::<i32>(); + thread::spawn(move || { + let res = thread::spawn(move || { + rx.recv().unwrap(); + }) + .join(); + assert!(res.is_err()); + }); + let _t = thread::spawn(move || { + thread::spawn(move || { + drop(tx); + }); + }); + } +} + +#[test] +fn oneshot_multi_thread_send_recv_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = channel::<Box<isize>>(); + let _t = thread::spawn(move || { + tx.send(box 10).unwrap(); + }); + assert!(*rx.recv().unwrap() == 10); + } +} + +#[test] +fn stream_send_recv_stress() { + for _ in 0..stress_factor() { + let (tx, rx) = channel(); + + send(tx, 0); + recv(rx, 0); + + fn send(tx: Sender<Box<i32>>, i: i32) { + if i == 10 { + return; + } + + thread::spawn(move || { + tx.send(box i).unwrap(); + send(tx, i + 1); + }); + } + + fn recv(rx: Receiver<Box<i32>>, i: i32) { + if i == 10 { + return; + } + + thread::spawn(move || { + assert!(*rx.recv().unwrap() == i); + recv(rx, i + 1); + }); + } + } +} + +#[test] +fn oneshot_single_thread_recv_timeout() { + let (tx, rx) = channel(); + tx.send(()).unwrap(); + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); + tx.send(()).unwrap(); + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); +} + +#[test] +fn stress_recv_timeout_two_threads() { + let (tx, rx) = channel(); + let stress = stress_factor() + 100; + let timeout = Duration::from_millis(100); + + thread::spawn(move || { + for i in 0..stress { + if i % 2 == 0 { + thread::sleep(timeout * 2); + } + tx.send(1usize).unwrap(); + } + }); + + let mut recv_count = 0; + loop { + match rx.recv_timeout(timeout) { + Ok(n) => { + assert_eq!(n, 1usize); + recv_count += 1; + } + Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Disconnected) => break, + } + } + + assert_eq!(recv_count, stress); +} + +#[test] +fn recv_timeout_upgrade() { + let (tx, rx) = channel::<()>(); + let timeout = Duration::from_millis(1); + let _tx_clone = tx.clone(); + + let start = Instant::now(); + assert_eq!(rx.recv_timeout(timeout), Err(RecvTimeoutError::Timeout)); + assert!(Instant::now() >= start + timeout); +} + +#[test] +fn stress_recv_timeout_shared() { + let (tx, rx) = channel(); + let stress = stress_factor() + 100; + + for i in 0..stress { + let tx = tx.clone(); + thread::spawn(move || { + thread::sleep(Duration::from_millis(i as u64 * 10)); + tx.send(1usize).unwrap(); + }); + } + + drop(tx); + + let mut recv_count = 0; + loop { + match rx.recv_timeout(Duration::from_millis(10)) { + Ok(n) => { + assert_eq!(n, 1usize); + recv_count += 1; + } + Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Disconnected) => break, + } + } + + assert_eq!(recv_count, stress); +} + +#[test] +fn very_long_recv_timeout_wont_panic() { + let (tx, rx) = channel::<()>(); + let join_handle = thread::spawn(move || rx.recv_timeout(Duration::from_secs(u64::MAX))); + thread::sleep(Duration::from_secs(1)); + assert!(tx.send(()).is_ok()); + assert_eq!(join_handle.join().unwrap(), Ok(())); +} + +#[test] +fn recv_a_lot() { + // Regression test that we don't run out of stack in scheduler context + let (tx, rx) = channel(); + for _ in 0..10000 { + tx.send(()).unwrap(); + } + for _ in 0..10000 { + rx.recv().unwrap(); + } +} + +#[test] +fn shared_recv_timeout() { + let (tx, rx) = channel(); + let total = 5; + for _ in 0..total { + let tx = tx.clone(); + thread::spawn(move || { + tx.send(()).unwrap(); + }); + } + + for _ in 0..total { + rx.recv().unwrap(); + } + + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); + tx.send(()).unwrap(); + assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(())); +} + +#[test] +fn shared_chan_stress() { + let (tx, rx) = channel(); + let total = stress_factor() + 100; + for _ in 0..total { + let tx = tx.clone(); + thread::spawn(move || { + tx.send(()).unwrap(); + }); + } + + for _ in 0..total { + rx.recv().unwrap(); + } +} + +#[test] +fn test_nested_recv_iter() { + let (tx, rx) = channel::<i32>(); + let (total_tx, total_rx) = channel::<i32>(); + + let _t = thread::spawn(move || { + let mut acc = 0; + for x in rx.iter() { + acc += x; + } + total_tx.send(acc).unwrap(); + }); + + tx.send(3).unwrap(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + drop(tx); + assert_eq!(total_rx.recv().unwrap(), 6); +} + +#[test] +fn test_recv_iter_break() { + let (tx, rx) = channel::<i32>(); + let (count_tx, count_rx) = channel(); + + let _t = thread::spawn(move || { + let mut count = 0; + for x in rx.iter() { + if count >= 3 { + break; + } else { + count += x; + } + } + count_tx.send(count).unwrap(); + }); + + tx.send(2).unwrap(); + tx.send(2).unwrap(); + tx.send(2).unwrap(); + let _ = tx.send(2); + drop(tx); + assert_eq!(count_rx.recv().unwrap(), 4); +} + +#[test] +fn test_recv_try_iter() { + let (request_tx, request_rx) = channel(); + let (response_tx, response_rx) = channel(); + + // Request `x`s until we have `6`. + let t = thread::spawn(move || { + let mut count = 0; + loop { + for x in response_rx.try_iter() { + count += x; + if count == 6 { + return count; + } + } + request_tx.send(()).unwrap(); + } + }); + + for _ in request_rx.iter() { + if response_tx.send(2).is_err() { + break; + } + } + + assert_eq!(t.join().unwrap(), 6); +} + +#[test] +fn test_recv_into_iter_owned() { + let mut iter = { + let (tx, rx) = channel::<i32>(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + + rx.into_iter() + }; + assert_eq!(iter.next().unwrap(), 1); + assert_eq!(iter.next().unwrap(), 2); + assert_eq!(iter.next().is_none(), true); +} + +#[test] +fn test_recv_into_iter_borrowed() { + let (tx, rx) = channel::<i32>(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + drop(tx); + let mut iter = (&rx).into_iter(); + assert_eq!(iter.next().unwrap(), 1); + assert_eq!(iter.next().unwrap(), 2); + assert_eq!(iter.next().is_none(), true); +} + +#[test] +fn try_recv_states() { + let (tx1, rx1) = channel::<i32>(); + let (tx2, rx2) = channel::<()>(); + let (tx3, rx3) = channel::<()>(); + let _t = thread::spawn(move || { + rx2.recv().unwrap(); + tx1.send(1).unwrap(); + tx3.send(()).unwrap(); + rx2.recv().unwrap(); + drop(tx1); + tx3.send(()).unwrap(); + }); + + assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); + tx2.send(()).unwrap(); + rx3.recv().unwrap(); + assert_eq!(rx1.try_recv(), Ok(1)); + assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty)); + tx2.send(()).unwrap(); + rx3.recv().unwrap(); + assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected)); +} + +// This bug used to end up in a livelock inside of the Receiver destructor +// because the internal state of the Shared packet was corrupted +#[test] +fn destroy_upgraded_shared_port_when_sender_still_active() { + let (tx, rx) = channel(); + let (tx2, rx2) = channel(); + let _t = thread::spawn(move || { + rx.recv().unwrap(); // wait on a oneshot + drop(rx); // destroy a shared + tx2.send(()).unwrap(); + }); + // make sure the other thread has gone to sleep + for _ in 0..5000 { + thread::yield_now(); + } + + // upgrade to a shared chan and send a message + let t = tx.clone(); + drop(tx); + t.send(()).unwrap(); + + // wait for the child thread to exit before we exit + rx2.recv().unwrap(); +} + +#[test] +fn issue_32114() { + let (tx, _) = channel(); + let _ = tx.send(123); + assert_eq!(tx.send(123), Err(SendError(123))); +} diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index d7a4f00305c..0de71793834 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::cell::UnsafeCell; use crate::fmt; use crate::mem; @@ -515,245 +518,3 @@ pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex { pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag { &guard.lock.poison } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::sync::atomic::{AtomicUsize, Ordering}; - use crate::sync::mpsc::channel; - use crate::sync::{Arc, Condvar, Mutex}; - use crate::thread; - - struct Packet<T>(Arc<(Mutex<T>, Condvar)>); - - #[derive(Eq, PartialEq, Debug)] - struct NonCopy(i32); - - #[test] - fn smoke() { - let m = Mutex::new(()); - drop(m.lock().unwrap()); - drop(m.lock().unwrap()); - } - - #[test] - fn lots_and_lots() { - const J: u32 = 1000; - const K: u32 = 3; - - let m = Arc::new(Mutex::new(0)); - - fn inc(m: &Mutex<u32>) { - for _ in 0..J { - *m.lock().unwrap() += 1; - } - } - - let (tx, rx) = channel(); - for _ in 0..K { - let tx2 = tx.clone(); - let m2 = m.clone(); - thread::spawn(move || { - inc(&m2); - tx2.send(()).unwrap(); - }); - let tx2 = tx.clone(); - let m2 = m.clone(); - thread::spawn(move || { - inc(&m2); - tx2.send(()).unwrap(); - }); - } - - drop(tx); - for _ in 0..2 * K { - rx.recv().unwrap(); - } - assert_eq!(*m.lock().unwrap(), J * K * 2); - } - - #[test] - fn try_lock() { - let m = Mutex::new(()); - *m.try_lock().unwrap() = (); - } - - #[test] - fn test_into_inner() { - let m = Mutex::new(NonCopy(10)); - assert_eq!(m.into_inner().unwrap(), NonCopy(10)); - } - - #[test] - fn test_into_inner_drop() { - struct Foo(Arc<AtomicUsize>); - impl Drop for Foo { - fn drop(&mut self) { - self.0.fetch_add(1, Ordering::SeqCst); - } - } - let num_drops = Arc::new(AtomicUsize::new(0)); - let m = Mutex::new(Foo(num_drops.clone())); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - { - let _inner = m.into_inner().unwrap(); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - } - assert_eq!(num_drops.load(Ordering::SeqCst), 1); - } - - #[test] - fn test_into_inner_poison() { - let m = Arc::new(Mutex::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.lock().unwrap(); - panic!("test panic in inner thread to poison mutex"); - }) - .join(); - - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().into_inner() { - Err(e) => assert_eq!(e.into_inner(), NonCopy(10)), - Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x), - } - } - - #[test] - fn test_get_mut() { - let mut m = Mutex::new(NonCopy(10)); - *m.get_mut().unwrap() = NonCopy(20); - assert_eq!(m.into_inner().unwrap(), NonCopy(20)); - } - - #[test] - fn test_get_mut_poison() { - let m = Arc::new(Mutex::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.lock().unwrap(); - panic!("test panic in inner thread to poison mutex"); - }) - .join(); - - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().get_mut() { - Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)), - Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x), - } - } - - #[test] - fn test_mutex_arc_condvar() { - let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); - let packet2 = Packet(packet.0.clone()); - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - // wait until parent gets in - rx.recv().unwrap(); - let &(ref lock, ref cvar) = &*packet2.0; - let mut lock = lock.lock().unwrap(); - *lock = true; - cvar.notify_one(); - }); - - let &(ref lock, ref cvar) = &*packet.0; - let mut lock = lock.lock().unwrap(); - tx.send(()).unwrap(); - assert!(!*lock); - while !*lock { - lock = cvar.wait(lock).unwrap(); - } - } - - #[test] - fn test_arc_condvar_poison() { - let packet = Packet(Arc::new((Mutex::new(1), Condvar::new()))); - let packet2 = Packet(packet.0.clone()); - let (tx, rx) = channel(); - - let _t = thread::spawn(move || -> () { - rx.recv().unwrap(); - let &(ref lock, ref cvar) = &*packet2.0; - let _g = lock.lock().unwrap(); - cvar.notify_one(); - // Parent should fail when it wakes up. - panic!(); - }); - - let &(ref lock, ref cvar) = &*packet.0; - let mut lock = lock.lock().unwrap(); - tx.send(()).unwrap(); - while *lock == 1 { - match cvar.wait(lock) { - Ok(l) => { - lock = l; - assert_eq!(*lock, 1); - } - Err(..) => break, - } - } - } - - #[test] - fn test_mutex_arc_poison() { - let arc = Arc::new(Mutex::new(1)); - assert!(!arc.is_poisoned()); - let arc2 = arc.clone(); - let _ = thread::spawn(move || { - let lock = arc2.lock().unwrap(); - assert_eq!(*lock, 2); - }) - .join(); - assert!(arc.lock().is_err()); - assert!(arc.is_poisoned()); - } - - #[test] - fn test_mutex_arc_nested() { - // Tests nested mutexes and access - // to underlying data. - let arc = Arc::new(Mutex::new(1)); - let arc2 = Arc::new(Mutex::new(arc)); - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - let lock = arc2.lock().unwrap(); - let lock2 = lock.lock().unwrap(); - assert_eq!(*lock2, 1); - tx.send(()).unwrap(); - }); - rx.recv().unwrap(); - } - - #[test] - fn test_mutex_arc_access_in_unwind() { - let arc = Arc::new(Mutex::new(1)); - let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { - struct Unwinder { - i: Arc<Mutex<i32>>, - } - impl Drop for Unwinder { - fn drop(&mut self) { - *self.i.lock().unwrap() += 1; - } - } - let _u = Unwinder { i: arc2 }; - panic!(); - }) - .join(); - let lock = arc.lock().unwrap(); - assert_eq!(*lock, 2); - } - - #[test] - fn test_mutex_unsized() { - let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]); - { - let b = &mut *mutex.lock().unwrap(); - b[0] = 4; - b[2] = 5; - } - let comp: &[i32] = &[4, 2, 5]; - assert_eq!(&*mutex.lock().unwrap(), comp); - } -} diff --git a/library/std/src/sync/mutex/tests.rs b/library/std/src/sync/mutex/tests.rs new file mode 100644 index 00000000000..a1b5aeddcb6 --- /dev/null +++ b/library/std/src/sync/mutex/tests.rs @@ -0,0 +1,238 @@ +use crate::sync::atomic::{AtomicUsize, Ordering}; +use crate::sync::mpsc::channel; +use crate::sync::{Arc, Condvar, Mutex}; +use crate::thread; + +struct Packet<T>(Arc<(Mutex<T>, Condvar)>); + +#[derive(Eq, PartialEq, Debug)] +struct NonCopy(i32); + +#[test] +fn smoke() { + let m = Mutex::new(()); + drop(m.lock().unwrap()); + drop(m.lock().unwrap()); +} + +#[test] +fn lots_and_lots() { + const J: u32 = 1000; + const K: u32 = 3; + + let m = Arc::new(Mutex::new(0)); + + fn inc(m: &Mutex<u32>) { + for _ in 0..J { + *m.lock().unwrap() += 1; + } + } + + let (tx, rx) = channel(); + for _ in 0..K { + let tx2 = tx.clone(); + let m2 = m.clone(); + thread::spawn(move || { + inc(&m2); + tx2.send(()).unwrap(); + }); + let tx2 = tx.clone(); + let m2 = m.clone(); + thread::spawn(move || { + inc(&m2); + tx2.send(()).unwrap(); + }); + } + + drop(tx); + for _ in 0..2 * K { + rx.recv().unwrap(); + } + assert_eq!(*m.lock().unwrap(), J * K * 2); +} + +#[test] +fn try_lock() { + let m = Mutex::new(()); + *m.try_lock().unwrap() = (); +} + +#[test] +fn test_into_inner() { + let m = Mutex::new(NonCopy(10)); + assert_eq!(m.into_inner().unwrap(), NonCopy(10)); +} + +#[test] +fn test_into_inner_drop() { + struct Foo(Arc<AtomicUsize>); + impl Drop for Foo { + fn drop(&mut self) { + self.0.fetch_add(1, Ordering::SeqCst); + } + } + let num_drops = Arc::new(AtomicUsize::new(0)); + let m = Mutex::new(Foo(num_drops.clone())); + assert_eq!(num_drops.load(Ordering::SeqCst), 0); + { + let _inner = m.into_inner().unwrap(); + assert_eq!(num_drops.load(Ordering::SeqCst), 0); + } + assert_eq!(num_drops.load(Ordering::SeqCst), 1); +} + +#[test] +fn test_into_inner_poison() { + let m = Arc::new(Mutex::new(NonCopy(10))); + let m2 = m.clone(); + let _ = thread::spawn(move || { + let _lock = m2.lock().unwrap(); + panic!("test panic in inner thread to poison mutex"); + }) + .join(); + + assert!(m.is_poisoned()); + match Arc::try_unwrap(m).unwrap().into_inner() { + Err(e) => assert_eq!(e.into_inner(), NonCopy(10)), + Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x), + } +} + +#[test] +fn test_get_mut() { + let mut m = Mutex::new(NonCopy(10)); + *m.get_mut().unwrap() = NonCopy(20); + assert_eq!(m.into_inner().unwrap(), NonCopy(20)); +} + +#[test] +fn test_get_mut_poison() { + let m = Arc::new(Mutex::new(NonCopy(10))); + let m2 = m.clone(); + let _ = thread::spawn(move || { + let _lock = m2.lock().unwrap(); + panic!("test panic in inner thread to poison mutex"); + }) + .join(); + + assert!(m.is_poisoned()); + match Arc::try_unwrap(m).unwrap().get_mut() { + Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)), + Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x), + } +} + +#[test] +fn test_mutex_arc_condvar() { + let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); + let (tx, rx) = channel(); + let _t = thread::spawn(move || { + // wait until parent gets in + rx.recv().unwrap(); + let &(ref lock, ref cvar) = &*packet2.0; + let mut lock = lock.lock().unwrap(); + *lock = true; + cvar.notify_one(); + }); + + let &(ref lock, ref cvar) = &*packet.0; + let mut lock = lock.lock().unwrap(); + tx.send(()).unwrap(); + assert!(!*lock); + while !*lock { + lock = cvar.wait(lock).unwrap(); + } +} + +#[test] +fn test_arc_condvar_poison() { + let packet = Packet(Arc::new((Mutex::new(1), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); + let (tx, rx) = channel(); + + let _t = thread::spawn(move || -> () { + rx.recv().unwrap(); + let &(ref lock, ref cvar) = &*packet2.0; + let _g = lock.lock().unwrap(); + cvar.notify_one(); + // Parent should fail when it wakes up. + panic!(); + }); + + let &(ref lock, ref cvar) = &*packet.0; + let mut lock = lock.lock().unwrap(); + tx.send(()).unwrap(); + while *lock == 1 { + match cvar.wait(lock) { + Ok(l) => { + lock = l; + assert_eq!(*lock, 1); + } + Err(..) => break, + } + } +} + +#[test] +fn test_mutex_arc_poison() { + let arc = Arc::new(Mutex::new(1)); + assert!(!arc.is_poisoned()); + let arc2 = arc.clone(); + let _ = thread::spawn(move || { + let lock = arc2.lock().unwrap(); + assert_eq!(*lock, 2); + }) + .join(); + assert!(arc.lock().is_err()); + assert!(arc.is_poisoned()); +} + +#[test] +fn test_mutex_arc_nested() { + // Tests nested mutexes and access + // to underlying data. + let arc = Arc::new(Mutex::new(1)); + let arc2 = Arc::new(Mutex::new(arc)); + let (tx, rx) = channel(); + let _t = thread::spawn(move || { + let lock = arc2.lock().unwrap(); + let lock2 = lock.lock().unwrap(); + assert_eq!(*lock2, 1); + tx.send(()).unwrap(); + }); + rx.recv().unwrap(); +} + +#[test] +fn test_mutex_arc_access_in_unwind() { + let arc = Arc::new(Mutex::new(1)); + let arc2 = arc.clone(); + let _ = thread::spawn(move || -> () { + struct Unwinder { + i: Arc<Mutex<i32>>, + } + impl Drop for Unwinder { + fn drop(&mut self) { + *self.i.lock().unwrap() += 1; + } + } + let _u = Unwinder { i: arc2 }; + panic!(); + }) + .join(); + let lock = arc.lock().unwrap(); + assert_eq!(*lock, 2); +} + +#[test] +fn test_mutex_unsized() { + let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]); + { + let b = &mut *mutex.lock().unwrap(); + b[0] = 4; + b[2] = 5; + } + let comp: &[i32] = &[4, 2, 5]; + assert_eq!(&*mutex.lock().unwrap(), comp); +} diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 714ec3e8786..8fed369bffc 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -84,6 +84,9 @@ // processor. Because both use Acquire ordering such a reordering is not // allowed, so no need for SeqCst. +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::cell::Cell; use crate::fmt; use crate::marker; @@ -568,123 +571,3 @@ impl OnceState { self.set_state_on_drop_to.set(POISONED); } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use super::Once; - use crate::panic; - use crate::sync::mpsc::channel; - use crate::thread; - - #[test] - fn smoke_once() { - static O: Once = Once::new(); - let mut a = 0; - O.call_once(|| a += 1); - assert_eq!(a, 1); - O.call_once(|| a += 1); - assert_eq!(a, 1); - } - - #[test] - fn stampede_once() { - static O: Once = Once::new(); - static mut RUN: bool = false; - - let (tx, rx) = channel(); - for _ in 0..10 { - let tx = tx.clone(); - thread::spawn(move || { - for _ in 0..4 { - thread::yield_now() - } - unsafe { - O.call_once(|| { - assert!(!RUN); - RUN = true; - }); - assert!(RUN); - } - tx.send(()).unwrap(); - }); - } - - unsafe { - O.call_once(|| { - assert!(!RUN); - RUN = true; - }); - assert!(RUN); - } - - for _ in 0..10 { - rx.recv().unwrap(); - } - } - - #[test] - fn poison_bad() { - static O: Once = Once::new(); - - // poison the once - let t = panic::catch_unwind(|| { - O.call_once(|| panic!()); - }); - assert!(t.is_err()); - - // poisoning propagates - let t = panic::catch_unwind(|| { - O.call_once(|| {}); - }); - assert!(t.is_err()); - - // we can subvert poisoning, however - let mut called = false; - O.call_once_force(|p| { - called = true; - assert!(p.poisoned()) - }); - assert!(called); - - // once any success happens, we stop propagating the poison - O.call_once(|| {}); - } - - #[test] - fn wait_for_force_to_finish() { - static O: Once = Once::new(); - - // poison the once - let t = panic::catch_unwind(|| { - O.call_once(|| panic!()); - }); - assert!(t.is_err()); - - // make sure someone's waiting inside the once via a force - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - let t1 = thread::spawn(move || { - O.call_once_force(|p| { - assert!(p.poisoned()); - tx1.send(()).unwrap(); - rx2.recv().unwrap(); - }); - }); - - rx1.recv().unwrap(); - - // put another waiter on the once - let t2 = thread::spawn(|| { - let mut called = false; - O.call_once(|| { - called = true; - }); - assert!(!called); - }); - - tx2.send(()).unwrap(); - - assert!(t1.join().is_ok()); - assert!(t2.join().is_ok()); - } -} diff --git a/library/std/src/sync/once/tests.rs b/library/std/src/sync/once/tests.rs new file mode 100644 index 00000000000..fae2752526e --- /dev/null +++ b/library/std/src/sync/once/tests.rs @@ -0,0 +1,116 @@ +use super::Once; +use crate::panic; +use crate::sync::mpsc::channel; +use crate::thread; + +#[test] +fn smoke_once() { + static O: Once = Once::new(); + let mut a = 0; + O.call_once(|| a += 1); + assert_eq!(a, 1); + O.call_once(|| a += 1); + assert_eq!(a, 1); +} + +#[test] +fn stampede_once() { + static O: Once = Once::new(); + static mut RUN: bool = false; + + let (tx, rx) = channel(); + for _ in 0..10 { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..4 { + thread::yield_now() + } + unsafe { + O.call_once(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + tx.send(()).unwrap(); + }); + } + + unsafe { + O.call_once(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + + for _ in 0..10 { + rx.recv().unwrap(); + } +} + +#[test] +fn poison_bad() { + static O: Once = Once::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.call_once(|| panic!()); + }); + assert!(t.is_err()); + + // poisoning propagates + let t = panic::catch_unwind(|| { + O.call_once(|| {}); + }); + assert!(t.is_err()); + + // we can subvert poisoning, however + let mut called = false; + O.call_once_force(|p| { + called = true; + assert!(p.poisoned()) + }); + assert!(called); + + // once any success happens, we stop propagating the poison + O.call_once(|| {}); +} + +#[test] +fn wait_for_force_to_finish() { + static O: Once = Once::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.call_once(|| panic!()); + }); + assert!(t.is_err()); + + // make sure someone's waiting inside the once via a force + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + let t1 = thread::spawn(move || { + O.call_once_force(|p| { + assert!(p.poisoned()); + tx1.send(()).unwrap(); + rx2.recv().unwrap(); + }); + }); + + rx1.recv().unwrap(); + + // put another waiter on the once + let t2 = thread::spawn(|| { + let mut called = false; + O.call_once(|| { + called = true; + }); + assert!(!called); + }); + + tx2.send(()).unwrap(); + + assert!(t1.join().is_ok()); + assert!(t2.join().is_ok()); +} diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 586093c916d..2d219c2c7dd 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::cell::UnsafeCell; use crate::fmt; use crate::mem; @@ -538,254 +541,3 @@ impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> { } } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::sync::atomic::{AtomicUsize, Ordering}; - use crate::sync::mpsc::channel; - use crate::sync::{Arc, RwLock, TryLockError}; - use crate::thread; - use rand::{self, Rng}; - - #[derive(Eq, PartialEq, Debug)] - struct NonCopy(i32); - - #[test] - fn smoke() { - let l = RwLock::new(()); - drop(l.read().unwrap()); - drop(l.write().unwrap()); - drop((l.read().unwrap(), l.read().unwrap())); - drop(l.write().unwrap()); - } - - #[test] - fn frob() { - const N: u32 = 10; - const M: usize = 1000; - - let r = Arc::new(RwLock::new(())); - - let (tx, rx) = channel::<()>(); - for _ in 0..N { - let tx = tx.clone(); - let r = r.clone(); - thread::spawn(move || { - let mut rng = rand::thread_rng(); - for _ in 0..M { - if rng.gen_bool(1.0 / (N as f64)) { - drop(r.write().unwrap()); - } else { - drop(r.read().unwrap()); - } - } - drop(tx); - }); - } - drop(tx); - let _ = rx.recv(); - } - - #[test] - fn test_rw_arc_poison_wr() { - let arc = Arc::new(RwLock::new(1)); - let arc2 = arc.clone(); - let _: Result<(), _> = thread::spawn(move || { - let _lock = arc2.write().unwrap(); - panic!(); - }) - .join(); - assert!(arc.read().is_err()); - } - - #[test] - fn test_rw_arc_poison_ww() { - let arc = Arc::new(RwLock::new(1)); - assert!(!arc.is_poisoned()); - let arc2 = arc.clone(); - let _: Result<(), _> = thread::spawn(move || { - let _lock = arc2.write().unwrap(); - panic!(); - }) - .join(); - assert!(arc.write().is_err()); - assert!(arc.is_poisoned()); - } - - #[test] - fn test_rw_arc_no_poison_rr() { - let arc = Arc::new(RwLock::new(1)); - let arc2 = arc.clone(); - let _: Result<(), _> = thread::spawn(move || { - let _lock = arc2.read().unwrap(); - panic!(); - }) - .join(); - let lock = arc.read().unwrap(); - assert_eq!(*lock, 1); - } - #[test] - fn test_rw_arc_no_poison_rw() { - let arc = Arc::new(RwLock::new(1)); - let arc2 = arc.clone(); - let _: Result<(), _> = thread::spawn(move || { - let _lock = arc2.read().unwrap(); - panic!() - }) - .join(); - let lock = arc.write().unwrap(); - assert_eq!(*lock, 1); - } - - #[test] - fn test_rw_arc() { - let arc = Arc::new(RwLock::new(0)); - let arc2 = arc.clone(); - let (tx, rx) = channel(); - - thread::spawn(move || { - let mut lock = arc2.write().unwrap(); - for _ in 0..10 { - let tmp = *lock; - *lock = -1; - thread::yield_now(); - *lock = tmp + 1; - } - tx.send(()).unwrap(); - }); - - // Readers try to catch the writer in the act - let mut children = Vec::new(); - for _ in 0..5 { - let arc3 = arc.clone(); - children.push(thread::spawn(move || { - let lock = arc3.read().unwrap(); - assert!(*lock >= 0); - })); - } - - // Wait for children to pass their asserts - for r in children { - assert!(r.join().is_ok()); - } - - // Wait for writer to finish - rx.recv().unwrap(); - let lock = arc.read().unwrap(); - assert_eq!(*lock, 10); - } - - #[test] - fn test_rw_arc_access_in_unwind() { - let arc = Arc::new(RwLock::new(1)); - let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { - struct Unwinder { - i: Arc<RwLock<isize>>, - } - impl Drop for Unwinder { - fn drop(&mut self) { - let mut lock = self.i.write().unwrap(); - *lock += 1; - } - } - let _u = Unwinder { i: arc2 }; - panic!(); - }) - .join(); - let lock = arc.read().unwrap(); - assert_eq!(*lock, 2); - } - - #[test] - fn test_rwlock_unsized() { - let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]); - { - let b = &mut *rw.write().unwrap(); - b[0] = 4; - b[2] = 5; - } - let comp: &[i32] = &[4, 2, 5]; - assert_eq!(&*rw.read().unwrap(), comp); - } - - #[test] - fn test_rwlock_try_write() { - let lock = RwLock::new(0isize); - let read_guard = lock.read().unwrap(); - - let write_result = lock.try_write(); - match write_result { - Err(TryLockError::WouldBlock) => (), - Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"), - Err(_) => assert!(false, "unexpected error"), - } - - drop(read_guard); - } - - #[test] - fn test_into_inner() { - let m = RwLock::new(NonCopy(10)); - assert_eq!(m.into_inner().unwrap(), NonCopy(10)); - } - - #[test] - fn test_into_inner_drop() { - struct Foo(Arc<AtomicUsize>); - impl Drop for Foo { - fn drop(&mut self) { - self.0.fetch_add(1, Ordering::SeqCst); - } - } - let num_drops = Arc::new(AtomicUsize::new(0)); - let m = RwLock::new(Foo(num_drops.clone())); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - { - let _inner = m.into_inner().unwrap(); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - } - assert_eq!(num_drops.load(Ordering::SeqCst), 1); - } - - #[test] - fn test_into_inner_poison() { - let m = Arc::new(RwLock::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.write().unwrap(); - panic!("test panic in inner thread to poison RwLock"); - }) - .join(); - - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().into_inner() { - Err(e) => assert_eq!(e.into_inner(), NonCopy(10)), - Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {:?}", x), - } - } - - #[test] - fn test_get_mut() { - let mut m = RwLock::new(NonCopy(10)); - *m.get_mut().unwrap() = NonCopy(20); - assert_eq!(m.into_inner().unwrap(), NonCopy(20)); - } - - #[test] - fn test_get_mut_poison() { - let m = Arc::new(RwLock::new(NonCopy(10))); - let m2 = m.clone(); - let _ = thread::spawn(move || { - let _lock = m2.write().unwrap(); - panic!("test panic in inner thread to poison RwLock"); - }) - .join(); - - assert!(m.is_poisoned()); - match Arc::try_unwrap(m).unwrap().get_mut() { - Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)), - Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {:?}", x), - } - } -} diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs new file mode 100644 index 00000000000..e9b74fb3ecc --- /dev/null +++ b/library/std/src/sync/rwlock/tests.rs @@ -0,0 +1,247 @@ +use crate::sync::atomic::{AtomicUsize, Ordering}; +use crate::sync::mpsc::channel; +use crate::sync::{Arc, RwLock, TryLockError}; +use crate::thread; +use rand::{self, Rng}; + +#[derive(Eq, PartialEq, Debug)] +struct NonCopy(i32); + +#[test] +fn smoke() { + let l = RwLock::new(()); + drop(l.read().unwrap()); + drop(l.write().unwrap()); + drop((l.read().unwrap(), l.read().unwrap())); + drop(l.write().unwrap()); +} + +#[test] +fn frob() { + const N: u32 = 10; + const M: usize = 1000; + + let r = Arc::new(RwLock::new(())); + + let (tx, rx) = channel::<()>(); + for _ in 0..N { + let tx = tx.clone(); + let r = r.clone(); + thread::spawn(move || { + let mut rng = rand::thread_rng(); + for _ in 0..M { + if rng.gen_bool(1.0 / (N as f64)) { + drop(r.write().unwrap()); + } else { + drop(r.read().unwrap()); + } + } + drop(tx); + }); + } + drop(tx); + let _ = rx.recv(); +} + +#[test] +fn test_rw_arc_poison_wr() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let _lock = arc2.write().unwrap(); + panic!(); + }) + .join(); + assert!(arc.read().is_err()); +} + +#[test] +fn test_rw_arc_poison_ww() { + let arc = Arc::new(RwLock::new(1)); + assert!(!arc.is_poisoned()); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let _lock = arc2.write().unwrap(); + panic!(); + }) + .join(); + assert!(arc.write().is_err()); + assert!(arc.is_poisoned()); +} + +#[test] +fn test_rw_arc_no_poison_rr() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let _lock = arc2.read().unwrap(); + panic!(); + }) + .join(); + let lock = arc.read().unwrap(); + assert_eq!(*lock, 1); +} +#[test] +fn test_rw_arc_no_poison_rw() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _: Result<(), _> = thread::spawn(move || { + let _lock = arc2.read().unwrap(); + panic!() + }) + .join(); + let lock = arc.write().unwrap(); + assert_eq!(*lock, 1); +} + +#[test] +fn test_rw_arc() { + let arc = Arc::new(RwLock::new(0)); + let arc2 = arc.clone(); + let (tx, rx) = channel(); + + thread::spawn(move || { + let mut lock = arc2.write().unwrap(); + for _ in 0..10 { + let tmp = *lock; + *lock = -1; + thread::yield_now(); + *lock = tmp + 1; + } + tx.send(()).unwrap(); + }); + + // Readers try to catch the writer in the act + let mut children = Vec::new(); + for _ in 0..5 { + let arc3 = arc.clone(); + children.push(thread::spawn(move || { + let lock = arc3.read().unwrap(); + assert!(*lock >= 0); + })); + } + + // Wait for children to pass their asserts + for r in children { + assert!(r.join().is_ok()); + } + + // Wait for writer to finish + rx.recv().unwrap(); + let lock = arc.read().unwrap(); + assert_eq!(*lock, 10); +} + +#[test] +fn test_rw_arc_access_in_unwind() { + let arc = Arc::new(RwLock::new(1)); + let arc2 = arc.clone(); + let _ = thread::spawn(move || -> () { + struct Unwinder { + i: Arc<RwLock<isize>>, + } + impl Drop for Unwinder { + fn drop(&mut self) { + let mut lock = self.i.write().unwrap(); + *lock += 1; + } + } + let _u = Unwinder { i: arc2 }; + panic!(); + }) + .join(); + let lock = arc.read().unwrap(); + assert_eq!(*lock, 2); +} + +#[test] +fn test_rwlock_unsized() { + let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]); + { + let b = &mut *rw.write().unwrap(); + b[0] = 4; + b[2] = 5; + } + let comp: &[i32] = &[4, 2, 5]; + assert_eq!(&*rw.read().unwrap(), comp); +} + +#[test] +fn test_rwlock_try_write() { + let lock = RwLock::new(0isize); + let read_guard = lock.read().unwrap(); + + let write_result = lock.try_write(); + match write_result { + Err(TryLockError::WouldBlock) => (), + Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"), + Err(_) => assert!(false, "unexpected error"), + } + + drop(read_guard); +} + +#[test] +fn test_into_inner() { + let m = RwLock::new(NonCopy(10)); + assert_eq!(m.into_inner().unwrap(), NonCopy(10)); +} + +#[test] +fn test_into_inner_drop() { + struct Foo(Arc<AtomicUsize>); + impl Drop for Foo { + fn drop(&mut self) { + self.0.fetch_add(1, Ordering::SeqCst); + } + } + let num_drops = Arc::new(AtomicUsize::new(0)); + let m = RwLock::new(Foo(num_drops.clone())); + assert_eq!(num_drops.load(Ordering::SeqCst), 0); + { + let _inner = m.into_inner().unwrap(); + assert_eq!(num_drops.load(Ordering::SeqCst), 0); + } + assert_eq!(num_drops.load(Ordering::SeqCst), 1); +} + +#[test] +fn test_into_inner_poison() { + let m = Arc::new(RwLock::new(NonCopy(10))); + let m2 = m.clone(); + let _ = thread::spawn(move || { + let _lock = m2.write().unwrap(); + panic!("test panic in inner thread to poison RwLock"); + }) + .join(); + + assert!(m.is_poisoned()); + match Arc::try_unwrap(m).unwrap().into_inner() { + Err(e) => assert_eq!(e.into_inner(), NonCopy(10)), + Ok(x) => panic!("into_inner of poisoned RwLock is Ok: {:?}", x), + } +} + +#[test] +fn test_get_mut() { + let mut m = RwLock::new(NonCopy(10)); + *m.get_mut().unwrap() = NonCopy(20); + assert_eq!(m.into_inner().unwrap(), NonCopy(20)); +} + +#[test] +fn test_get_mut_poison() { + let m = Arc::new(RwLock::new(NonCopy(10))); + let m2 = m.clone(); + let _ = thread::spawn(move || { + let _lock = m2.write().unwrap(); + panic!("test panic in inner thread to poison RwLock"); + }) + .join(); + + assert!(m.is_poisoned()); + match Arc::try_unwrap(m).unwrap().get_mut() { + Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)), + Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {:?}", x), + } +} diff --git a/library/std/src/sys/sgx/abi/tls.rs b/library/std/src/sys/sgx/abi/tls.rs index 2b0485c4f03..0d8952b2f27 100644 --- a/library/std/src/sys/sgx/abi/tls.rs +++ b/library/std/src/sys/sgx/abi/tls.rs @@ -1,3 +1,5 @@ +mod sync_bitset; + use self::sync_bitset::*; use crate::cell::Cell; use crate::mem; @@ -125,117 +127,3 @@ impl Tls { TLS_KEY_IN_USE.clear(key.to_index()); } } - -mod sync_bitset { - use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS}; - use crate::iter::{Enumerate, Peekable}; - use crate::slice::Iter; - use crate::sync::atomic::{AtomicUsize, Ordering}; - - /// A bitset that can be used synchronously. - pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]); - - pub(super) const SYNC_BITSET_INIT: SyncBitset = - SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]); - - impl SyncBitset { - pub fn get(&self, index: usize) -> bool { - let (hi, lo) = Self::split(index); - (self.0[hi].load(Ordering::Relaxed) & lo) != 0 - } - - /// Not atomic. - pub fn iter(&self) -> SyncBitsetIter<'_> { - SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 } - } - - pub fn clear(&self, index: usize) { - let (hi, lo) = Self::split(index); - self.0[hi].fetch_and(!lo, Ordering::Relaxed); - } - - /// Sets any unset bit. Not atomic. Returns `None` if all bits were - /// observed to be set. - pub fn set(&self) -> Option<usize> { - 'elems: for (idx, elem) in self.0.iter().enumerate() { - let mut current = elem.load(Ordering::Relaxed); - loop { - if 0 == !current { - continue 'elems; - } - let trailing_ones = (!current).trailing_zeros() as usize; - match elem.compare_exchange( - current, - current | (1 << trailing_ones), - Ordering::AcqRel, - Ordering::Relaxed, - ) { - Ok(_) => return Some(idx * USIZE_BITS + trailing_ones), - Err(previous) => current = previous, - } - } - } - None - } - - fn split(index: usize) -> (usize, usize) { - (index / USIZE_BITS, 1 << (index % USIZE_BITS)) - } - } - - pub(super) struct SyncBitsetIter<'a> { - iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>, - elem_idx: usize, - } - - impl<'a> Iterator for SyncBitsetIter<'a> { - type Item = usize; - - fn next(&mut self) -> Option<usize> { - self.iter.peek().cloned().and_then(|(idx, elem)| { - let elem = elem.load(Ordering::Relaxed); - let low_mask = (1 << self.elem_idx) - 1; - let next = elem & !low_mask; - let next_idx = next.trailing_zeros() as usize; - self.elem_idx = next_idx + 1; - if self.elem_idx >= 64 { - self.elem_idx = 0; - self.iter.next(); - } - match next_idx { - 64 => self.next(), - _ => Some(idx * USIZE_BITS + next_idx), - } - }) - } - } - - #[cfg(test)] - mod tests { - use super::*; - - fn test_data(bitset: [usize; 2], bit_indices: &[usize]) { - let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]); - assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices); - for &i in bit_indices { - assert!(set.get(i)); - } - } - - #[test] - fn iter() { - test_data([0b0110_1001, 0], &[0, 3, 5, 6]); - test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]); - test_data([0, 0], &[]); - } - - #[test] - fn set_get_clear() { - let set = SYNC_BITSET_INIT; - let key = set.set().unwrap(); - assert!(set.get(key)); - set.clear(key); - assert!(!set.get(key)); - } - } -} diff --git a/library/std/src/sys/sgx/abi/tls/sync_bitset.rs b/library/std/src/sys/sgx/abi/tls/sync_bitset.rs new file mode 100644 index 00000000000..4eeff8f6ef7 --- /dev/null +++ b/library/std/src/sys/sgx/abi/tls/sync_bitset.rs @@ -0,0 +1,85 @@ +#[cfg(test)] +mod tests; + +use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS}; +use crate::iter::{Enumerate, Peekable}; +use crate::slice::Iter; +use crate::sync::atomic::{AtomicUsize, Ordering}; + +/// A bitset that can be used synchronously. +pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]); + +pub(super) const SYNC_BITSET_INIT: SyncBitset = + SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]); + +impl SyncBitset { + pub fn get(&self, index: usize) -> bool { + let (hi, lo) = Self::split(index); + (self.0[hi].load(Ordering::Relaxed) & lo) != 0 + } + + /// Not atomic. + pub fn iter(&self) -> SyncBitsetIter<'_> { + SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 } + } + + pub fn clear(&self, index: usize) { + let (hi, lo) = Self::split(index); + self.0[hi].fetch_and(!lo, Ordering::Relaxed); + } + + /// Sets any unset bit. Not atomic. Returns `None` if all bits were + /// observed to be set. + pub fn set(&self) -> Option<usize> { + 'elems: for (idx, elem) in self.0.iter().enumerate() { + let mut current = elem.load(Ordering::Relaxed); + loop { + if 0 == !current { + continue 'elems; + } + let trailing_ones = (!current).trailing_zeros() as usize; + match elem.compare_exchange( + current, + current | (1 << trailing_ones), + Ordering::AcqRel, + Ordering::Relaxed, + ) { + Ok(_) => return Some(idx * USIZE_BITS + trailing_ones), + Err(previous) => current = previous, + } + } + } + None + } + + fn split(index: usize) -> (usize, usize) { + (index / USIZE_BITS, 1 << (index % USIZE_BITS)) + } +} + +pub(super) struct SyncBitsetIter<'a> { + iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>, + elem_idx: usize, +} + +impl<'a> Iterator for SyncBitsetIter<'a> { + type Item = usize; + + fn next(&mut self) -> Option<usize> { + self.iter.peek().cloned().and_then(|(idx, elem)| { + let elem = elem.load(Ordering::Relaxed); + let low_mask = (1 << self.elem_idx) - 1; + let next = elem & !low_mask; + let next_idx = next.trailing_zeros() as usize; + self.elem_idx = next_idx + 1; + if self.elem_idx >= 64 { + self.elem_idx = 0; + self.iter.next(); + } + match next_idx { + 64 => self.next(), + _ => Some(idx * USIZE_BITS + next_idx), + } + }) + } +} diff --git a/library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs b/library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs new file mode 100644 index 00000000000..d7eb2e139d0 --- /dev/null +++ b/library/std/src/sys/sgx/abi/tls/sync_bitset/tests.rs @@ -0,0 +1,25 @@ +use super::*; + +fn test_data(bitset: [usize; 2], bit_indices: &[usize]) { + let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]); + assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices); + for &i in bit_indices { + assert!(set.get(i)); + } +} + +#[test] +fn iter() { + test_data([0b0110_1001, 0], &[0, 3, 5, 6]); + test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]); + test_data([0, 0], &[]); +} + +#[test] +fn set_get_clear() { + let set = SYNC_BITSET_INIT; + let key = set.set().unwrap(); + assert!(set.get(key)); + set.clear(key); + assert!(!set.get(key)); +} diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs index 722b4f5e0ba..3bf2a7d8fb4 100644 --- a/library/std/src/sys/sgx/rwlock.rs +++ b/library/std/src/sys/sgx/rwlock.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::num::NonZeroUsize; use super::waitqueue::{ @@ -198,50 +201,3 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { (*p).unlock(); return 0; } - -#[cfg(test)] -mod tests { - use super::*; - use crate::mem::{self, MaybeUninit}; - use core::array::FixedSizeArray; - - // Verify that the bytes of initialized RWLock are the same as in - // libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to - // be changed too. - #[test] - fn test_c_rwlock_initializer() { - #[rustfmt::skip] - const RWLOCK_INIT: &[u8] = &[ - /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - ]; - - #[inline(never)] - fn zero_stack() { - test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed()); - } - - #[inline(never)] - unsafe fn rwlock_new(init: &mut MaybeUninit<RWLock>) { - init.write(RWLock::new()); - } - - unsafe { - // try hard to make sure that the padding/unused bytes in RWLock - // get initialized as 0. If the assertion below fails, that might - // just be an issue with the test code and not with the value of - // RWLOCK_INIT. - zero_stack(); - let mut init = MaybeUninit::<RWLock>::zeroed(); - rwlock_new(&mut init); - assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT) - }; - } -} diff --git a/library/std/src/sys/sgx/rwlock/tests.rs b/library/std/src/sys/sgx/rwlock/tests.rs new file mode 100644 index 00000000000..05b36c633f8 --- /dev/null +++ b/library/std/src/sys/sgx/rwlock/tests.rs @@ -0,0 +1,43 @@ +use super::*; +use crate::mem::{self, MaybeUninit}; +use core::array::FixedSizeArray; + +// Verify that the bytes of initialized RWLock are the same as in +// libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to +// be changed too. +#[test] +fn test_c_rwlock_initializer() { + #[rustfmt::skip] + const RWLOCK_INIT: &[u8] = &[ + /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + ]; + + #[inline(never)] + fn zero_stack() { + test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed()); + } + + #[inline(never)] + unsafe fn rwlock_new(init: &mut MaybeUninit<RWLock>) { + init.write(RWLock::new()); + } + + unsafe { + // try hard to make sure that the padding/unused bytes in RWLock + // get initialized as 0. If the assertion below fails, that might + // just be an issue with the test code and not with the value of + // RWLOCK_INIT. + zero_stack(); + let mut init = MaybeUninit::<RWLock>::zeroed(); + rwlock_new(&mut init); + assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT) + }; +} diff --git a/library/std/src/sys/sgx/waitqueue.rs b/library/std/src/sys/sgx/waitqueue.rs index 070afa55f30..e464dc3ee9d 100644 --- a/library/std/src/sys/sgx/waitqueue.rs +++ b/library/std/src/sys/sgx/waitqueue.rs @@ -9,6 +9,18 @@ //! Since userspace may send spurious wake-ups, the wakeup event state is //! recorded in the enclave. The wakeup event state is protected by a spinlock. //! The queue and associated wait state are stored in a `WaitVariable`. + +#[cfg(test)] +mod tests; + +/// A doubly-linked list where callers are in charge of memory allocation +/// of the nodes in the list. +mod unsafe_list; + +/// Trivial spinlock-based implementation of `sync::Mutex`. +// FIXME: Perhaps use Intel TSX to avoid locking? +mod spin_mutex; + use crate::num::NonZeroUsize; use crate::ops::{Deref, DerefMut}; use crate::time::Duration; @@ -231,389 +243,3 @@ impl WaitQueue { } } } - -/// A doubly-linked list where callers are in charge of memory allocation -/// of the nodes in the list. -mod unsafe_list { - use crate::mem; - use crate::ptr::NonNull; - - pub struct UnsafeListEntry<T> { - next: NonNull<UnsafeListEntry<T>>, - prev: NonNull<UnsafeListEntry<T>>, - value: Option<T>, - } - - impl<T> UnsafeListEntry<T> { - fn dummy() -> Self { - UnsafeListEntry { next: NonNull::dangling(), prev: NonNull::dangling(), value: None } - } - - pub fn new(value: T) -> Self { - UnsafeListEntry { value: Some(value), ..Self::dummy() } - } - } - - pub struct UnsafeList<T> { - head_tail: NonNull<UnsafeListEntry<T>>, - head_tail_entry: Option<UnsafeListEntry<T>>, - } - - impl<T> UnsafeList<T> { - pub const fn new() -> Self { - unsafe { - UnsafeList { head_tail: NonNull::new_unchecked(1 as _), head_tail_entry: None } - } - } - - unsafe fn init(&mut self) { - if self.head_tail_entry.is_none() { - self.head_tail_entry = Some(UnsafeListEntry::dummy()); - self.head_tail = NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap()); - self.head_tail.as_mut().next = self.head_tail; - self.head_tail.as_mut().prev = self.head_tail; - } - } - - pub fn is_empty(&self) -> bool { - unsafe { - if self.head_tail_entry.is_some() { - let first = self.head_tail.as_ref().next; - if first == self.head_tail { - // ,-------> /---------\ next ---, - // | |head_tail| | - // `--- prev \---------/ <-------` - rtassert!(self.head_tail.as_ref().prev == first); - true - } else { - false - } - } else { - true - } - } - } - - /// Pushes an entry onto the back of the list. - /// - /// # Safety - /// - /// The entry must remain allocated until the entry is removed from the - /// list AND the caller who popped is done using the entry. Special - /// care must be taken in the caller of `push` to ensure unwinding does - /// not destroy the stack frame containing the entry. - pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry<T>) -> &'a T { - self.init(); - - // BEFORE: - // /---------\ next ---> /---------\ - // ... |prev_tail| |head_tail| ... - // \---------/ <--- prev \---------/ - // - // AFTER: - // /---------\ next ---> /-----\ next ---> /---------\ - // ... |prev_tail| |entry| |head_tail| ... - // \---------/ <--- prev \-----/ <--- prev \---------/ - let mut entry = NonNull::new_unchecked(entry); - let mut prev_tail = mem::replace(&mut self.head_tail.as_mut().prev, entry); - entry.as_mut().prev = prev_tail; - entry.as_mut().next = self.head_tail; - prev_tail.as_mut().next = entry; - // unwrap ok: always `Some` on non-dummy entries - (*entry.as_ptr()).value.as_ref().unwrap() - } - - /// Pops an entry from the front of the list. - /// - /// # Safety - /// - /// The caller must make sure to synchronize ending the borrow of the - /// return value and deallocation of the containing entry. - pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> { - self.init(); - - if self.is_empty() { - None - } else { - // BEFORE: - // /---------\ next ---> /-----\ next ---> /------\ - // ... |head_tail| |first| |second| ... - // \---------/ <--- prev \-----/ <--- prev \------/ - // - // AFTER: - // /---------\ next ---> /------\ - // ... |head_tail| |second| ... - // \---------/ <--- prev \------/ - let mut first = self.head_tail.as_mut().next; - let mut second = first.as_mut().next; - self.head_tail.as_mut().next = second; - second.as_mut().prev = self.head_tail; - first.as_mut().next = NonNull::dangling(); - first.as_mut().prev = NonNull::dangling(); - // unwrap ok: always `Some` on non-dummy entries - Some((*first.as_ptr()).value.as_ref().unwrap()) - } - } - - /// Removes an entry from the list. - /// - /// # Safety - /// - /// The caller must ensure that `entry` has been pushed onto `self` - /// prior to this call and has not moved since then. - pub unsafe fn remove(&mut self, entry: &mut UnsafeListEntry<T>) { - rtassert!(!self.is_empty()); - // BEFORE: - // /----\ next ---> /-----\ next ---> /----\ - // ... |prev| |entry| |next| ... - // \----/ <--- prev \-----/ <--- prev \----/ - // - // AFTER: - // /----\ next ---> /----\ - // ... |prev| |next| ... - // \----/ <--- prev \----/ - let mut prev = entry.prev; - let mut next = entry.next; - prev.as_mut().next = next; - next.as_mut().prev = prev; - entry.next = NonNull::dangling(); - entry.prev = NonNull::dangling(); - } - } - - #[cfg(test)] - mod tests { - use super::*; - use crate::cell::Cell; - - unsafe fn assert_empty<T>(list: &mut UnsafeList<T>) { - assert!(list.pop().is_none(), "assertion failed: list is not empty"); - } - - #[test] - fn init_empty() { - unsafe { - assert_empty(&mut UnsafeList::<i32>::new()); - } - } - - #[test] - fn push_pop() { - unsafe { - let mut node = UnsafeListEntry::new(1234); - let mut list = UnsafeList::new(); - assert_eq!(list.push(&mut node), &1234); - assert_eq!(list.pop().unwrap(), &1234); - assert_empty(&mut list); - } - } - - #[test] - fn push_remove() { - unsafe { - let mut node = UnsafeListEntry::new(1234); - let mut list = UnsafeList::new(); - assert_eq!(list.push(&mut node), &1234); - list.remove(&mut node); - assert_empty(&mut list); - } - } - - #[test] - fn push_remove_pop() { - unsafe { - let mut node1 = UnsafeListEntry::new(11); - let mut node2 = UnsafeListEntry::new(12); - let mut node3 = UnsafeListEntry::new(13); - let mut node4 = UnsafeListEntry::new(14); - let mut node5 = UnsafeListEntry::new(15); - let mut list = UnsafeList::new(); - assert_eq!(list.push(&mut node1), &11); - assert_eq!(list.push(&mut node2), &12); - assert_eq!(list.push(&mut node3), &13); - assert_eq!(list.push(&mut node4), &14); - assert_eq!(list.push(&mut node5), &15); - - list.remove(&mut node1); - assert_eq!(list.pop().unwrap(), &12); - list.remove(&mut node3); - assert_eq!(list.pop().unwrap(), &14); - list.remove(&mut node5); - assert_empty(&mut list); - - assert_eq!(list.push(&mut node1), &11); - assert_eq!(list.pop().unwrap(), &11); - assert_empty(&mut list); - - assert_eq!(list.push(&mut node3), &13); - assert_eq!(list.push(&mut node4), &14); - list.remove(&mut node3); - list.remove(&mut node4); - assert_empty(&mut list); - } - } - - #[test] - fn complex_pushes_pops() { - unsafe { - let mut node1 = UnsafeListEntry::new(1234); - let mut node2 = UnsafeListEntry::new(4567); - let mut node3 = UnsafeListEntry::new(9999); - let mut node4 = UnsafeListEntry::new(8642); - let mut list = UnsafeList::new(); - list.push(&mut node1); - list.push(&mut node2); - assert_eq!(list.pop().unwrap(), &1234); - list.push(&mut node3); - assert_eq!(list.pop().unwrap(), &4567); - assert_eq!(list.pop().unwrap(), &9999); - assert_empty(&mut list); - list.push(&mut node4); - assert_eq!(list.pop().unwrap(), &8642); - assert_empty(&mut list); - } - } - - #[test] - fn cell() { - unsafe { - let mut node = UnsafeListEntry::new(Cell::new(0)); - let mut list = UnsafeList::new(); - let noderef = list.push(&mut node); - assert_eq!(noderef.get(), 0); - list.pop().unwrap().set(1); - assert_empty(&mut list); - assert_eq!(noderef.get(), 1); - } - } - } -} - -/// Trivial spinlock-based implementation of `sync::Mutex`. -// FIXME: Perhaps use Intel TSX to avoid locking? -mod spin_mutex { - use crate::cell::UnsafeCell; - use crate::ops::{Deref, DerefMut}; - use crate::sync::atomic::{spin_loop_hint, AtomicBool, Ordering}; - - #[derive(Default)] - pub struct SpinMutex<T> { - value: UnsafeCell<T>, - lock: AtomicBool, - } - - unsafe impl<T: Send> Send for SpinMutex<T> {} - unsafe impl<T: Send> Sync for SpinMutex<T> {} - - pub struct SpinMutexGuard<'a, T: 'a> { - mutex: &'a SpinMutex<T>, - } - - impl<'a, T> !Send for SpinMutexGuard<'a, T> {} - unsafe impl<'a, T: Sync> Sync for SpinMutexGuard<'a, T> {} - - impl<T> SpinMutex<T> { - pub const fn new(value: T) -> Self { - SpinMutex { value: UnsafeCell::new(value), lock: AtomicBool::new(false) } - } - - #[inline(always)] - pub fn lock(&self) -> SpinMutexGuard<'_, T> { - loop { - match self.try_lock() { - None => { - while self.lock.load(Ordering::Relaxed) { - spin_loop_hint() - } - } - Some(guard) => return guard, - } - } - } - - #[inline(always)] - pub fn try_lock(&self) -> Option<SpinMutexGuard<'_, T>> { - if !self.lock.compare_and_swap(false, true, Ordering::Acquire) { - Some(SpinMutexGuard { mutex: self }) - } else { - None - } - } - } - - /// Lock the Mutex or return false. - pub macro try_lock_or_false($e:expr) { - if let Some(v) = $e.try_lock() { v } else { return false } - } - - impl<'a, T> Deref for SpinMutexGuard<'a, T> { - type Target = T; - - fn deref(&self) -> &T { - unsafe { &*self.mutex.value.get() } - } - } - - impl<'a, T> DerefMut for SpinMutexGuard<'a, T> { - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.mutex.value.get() } - } - } - - impl<'a, T> Drop for SpinMutexGuard<'a, T> { - fn drop(&mut self) { - self.mutex.lock.store(false, Ordering::Release) - } - } - - #[cfg(test)] - mod tests { - #![allow(deprecated)] - - use super::*; - use crate::sync::Arc; - use crate::thread; - use crate::time::Duration; - - #[test] - fn sleep() { - let mutex = Arc::new(SpinMutex::<i32>::default()); - let mutex2 = mutex.clone(); - let guard = mutex.lock(); - let t1 = thread::spawn(move || { - *mutex2.lock() = 1; - }); - - thread::sleep(Duration::from_millis(50)); - - assert_eq!(*guard, 0); - drop(guard); - t1.join().unwrap(); - assert_eq!(*mutex.lock(), 1); - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::sync::Arc; - use crate::thread; - - #[test] - fn queue() { - let wq = Arc::new(SpinMutex::<WaitVariable<()>>::default()); - let wq2 = wq.clone(); - - let locked = wq.lock(); - - let t1 = thread::spawn(move || { - // if we obtain the lock, the main thread should be waiting - assert!(WaitQueue::notify_one(wq2.lock()).is_ok()); - }); - - WaitQueue::wait(locked, || {}); - - t1.join().unwrap(); - } -} diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs new file mode 100644 index 00000000000..d99ce895da5 --- /dev/null +++ b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs @@ -0,0 +1,76 @@ +#[cfg(test)] +mod tests; + +use crate::cell::UnsafeCell; +use crate::ops::{Deref, DerefMut}; +use crate::sync::atomic::{spin_loop_hint, AtomicBool, Ordering}; + +#[derive(Default)] +pub struct SpinMutex<T> { + value: UnsafeCell<T>, + lock: AtomicBool, +} + +unsafe impl<T: Send> Send for SpinMutex<T> {} +unsafe impl<T: Send> Sync for SpinMutex<T> {} + +pub struct SpinMutexGuard<'a, T: 'a> { + mutex: &'a SpinMutex<T>, +} + +impl<'a, T> !Send for SpinMutexGuard<'a, T> {} +unsafe impl<'a, T: Sync> Sync for SpinMutexGuard<'a, T> {} + +impl<T> SpinMutex<T> { + pub const fn new(value: T) -> Self { + SpinMutex { value: UnsafeCell::new(value), lock: AtomicBool::new(false) } + } + + #[inline(always)] + pub fn lock(&self) -> SpinMutexGuard<'_, T> { + loop { + match self.try_lock() { + None => { + while self.lock.load(Ordering::Relaxed) { + spin_loop_hint() + } + } + Some(guard) => return guard, + } + } + } + + #[inline(always)] + pub fn try_lock(&self) -> Option<SpinMutexGuard<'_, T>> { + if !self.lock.compare_and_swap(false, true, Ordering::Acquire) { + Some(SpinMutexGuard { mutex: self }) + } else { + None + } + } +} + +/// Lock the Mutex or return false. +pub macro try_lock_or_false($e:expr) { + if let Some(v) = $e.try_lock() { v } else { return false } +} + +impl<'a, T> Deref for SpinMutexGuard<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + unsafe { &*self.mutex.value.get() } + } +} + +impl<'a, T> DerefMut for SpinMutexGuard<'a, T> { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.mutex.value.get() } + } +} + +impl<'a, T> Drop for SpinMutexGuard<'a, T> { + fn drop(&mut self) { + self.mutex.lock.store(false, Ordering::Release) + } +} diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs new file mode 100644 index 00000000000..4c5994bea61 --- /dev/null +++ b/library/std/src/sys/sgx/waitqueue/spin_mutex/tests.rs @@ -0,0 +1,23 @@ +#![allow(deprecated)] + +use super::*; +use crate::sync::Arc; +use crate::thread; +use crate::time::Duration; + +#[test] +fn sleep() { + let mutex = Arc::new(SpinMutex::<i32>::default()); + let mutex2 = mutex.clone(); + let guard = mutex.lock(); + let t1 = thread::spawn(move || { + *mutex2.lock() = 1; + }); + + thread::sleep(Duration::from_millis(50)); + + assert_eq!(*guard, 0); + drop(guard); + t1.join().unwrap(); + assert_eq!(*mutex.lock(), 1); +} diff --git a/library/std/src/sys/sgx/waitqueue/tests.rs b/library/std/src/sys/sgx/waitqueue/tests.rs new file mode 100644 index 00000000000..bf91fdd08ed --- /dev/null +++ b/library/std/src/sys/sgx/waitqueue/tests.rs @@ -0,0 +1,20 @@ +use super::*; +use crate::sync::Arc; +use crate::thread; + +#[test] +fn queue() { + let wq = Arc::new(SpinMutex::<WaitVariable<()>>::default()); + let wq2 = wq.clone(); + + let locked = wq.lock(); + + let t1 = thread::spawn(move || { + // if we obtain the lock, the main thread should be waiting + assert!(WaitQueue::notify_one(wq2.lock()).is_ok()); + }); + + WaitQueue::wait(locked, || {}); + + t1.join().unwrap(); +} diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs new file mode 100644 index 00000000000..7a246542739 --- /dev/null +++ b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs @@ -0,0 +1,146 @@ +#[cfg(test)] +mod tests; + +use crate::mem; +use crate::ptr::NonNull; + +pub struct UnsafeListEntry<T> { + next: NonNull<UnsafeListEntry<T>>, + prev: NonNull<UnsafeListEntry<T>>, + value: Option<T>, +} + +impl<T> UnsafeListEntry<T> { + fn dummy() -> Self { + UnsafeListEntry { next: NonNull::dangling(), prev: NonNull::dangling(), value: None } + } + + pub fn new(value: T) -> Self { + UnsafeListEntry { value: Some(value), ..Self::dummy() } + } +} + +pub struct UnsafeList<T> { + head_tail: NonNull<UnsafeListEntry<T>>, + head_tail_entry: Option<UnsafeListEntry<T>>, +} + +impl<T> UnsafeList<T> { + pub const fn new() -> Self { + unsafe { UnsafeList { head_tail: NonNull::new_unchecked(1 as _), head_tail_entry: None } } + } + + unsafe fn init(&mut self) { + if self.head_tail_entry.is_none() { + self.head_tail_entry = Some(UnsafeListEntry::dummy()); + self.head_tail = NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap()); + self.head_tail.as_mut().next = self.head_tail; + self.head_tail.as_mut().prev = self.head_tail; + } + } + + pub fn is_empty(&self) -> bool { + unsafe { + if self.head_tail_entry.is_some() { + let first = self.head_tail.as_ref().next; + if first == self.head_tail { + // ,-------> /---------\ next ---, + // | |head_tail| | + // `--- prev \---------/ <-------` + rtassert!(self.head_tail.as_ref().prev == first); + true + } else { + false + } + } else { + true + } + } + } + + /// Pushes an entry onto the back of the list. + /// + /// # Safety + /// + /// The entry must remain allocated until the entry is removed from the + /// list AND the caller who popped is done using the entry. Special + /// care must be taken in the caller of `push` to ensure unwinding does + /// not destroy the stack frame containing the entry. + pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry<T>) -> &'a T { + self.init(); + + // BEFORE: + // /---------\ next ---> /---------\ + // ... |prev_tail| |head_tail| ... + // \---------/ <--- prev \---------/ + // + // AFTER: + // /---------\ next ---> /-----\ next ---> /---------\ + // ... |prev_tail| |entry| |head_tail| ... + // \---------/ <--- prev \-----/ <--- prev \---------/ + let mut entry = NonNull::new_unchecked(entry); + let mut prev_tail = mem::replace(&mut self.head_tail.as_mut().prev, entry); + entry.as_mut().prev = prev_tail; + entry.as_mut().next = self.head_tail; + prev_tail.as_mut().next = entry; + // unwrap ok: always `Some` on non-dummy entries + (*entry.as_ptr()).value.as_ref().unwrap() + } + + /// Pops an entry from the front of the list. + /// + /// # Safety + /// + /// The caller must make sure to synchronize ending the borrow of the + /// return value and deallocation of the containing entry. + pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> { + self.init(); + + if self.is_empty() { + None + } else { + // BEFORE: + // /---------\ next ---> /-----\ next ---> /------\ + // ... |head_tail| |first| |second| ... + // \---------/ <--- prev \-----/ <--- prev \------/ + // + // AFTER: + // /---------\ next ---> /------\ + // ... |head_tail| |second| ... + // \---------/ <--- prev \------/ + let mut first = self.head_tail.as_mut().next; + let mut second = first.as_mut().next; + self.head_tail.as_mut().next = second; + second.as_mut().prev = self.head_tail; + first.as_mut().next = NonNull::dangling(); + first.as_mut().prev = NonNull::dangling(); + // unwrap ok: always `Some` on non-dummy entries + Some((*first.as_ptr()).value.as_ref().unwrap()) + } + } + + /// Removes an entry from the list. + /// + /// # Safety + /// + /// The caller must ensure that `entry` has been pushed onto `self` + /// prior to this call and has not moved since then. + pub unsafe fn remove(&mut self, entry: &mut UnsafeListEntry<T>) { + rtassert!(!self.is_empty()); + // BEFORE: + // /----\ next ---> /-----\ next ---> /----\ + // ... |prev| |entry| |next| ... + // \----/ <--- prev \-----/ <--- prev \----/ + // + // AFTER: + // /----\ next ---> /----\ + // ... |prev| |next| ... + // \----/ <--- prev \----/ + let mut prev = entry.prev; + let mut next = entry.next; + prev.as_mut().next = next; + next.as_mut().prev = prev; + entry.next = NonNull::dangling(); + entry.prev = NonNull::dangling(); + } +} diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs new file mode 100644 index 00000000000..1f031ed1959 --- /dev/null +++ b/library/std/src/sys/sgx/waitqueue/unsafe_list/tests.rs @@ -0,0 +1,103 @@ +use super::*; +use crate::cell::Cell; + +unsafe fn assert_empty<T>(list: &mut UnsafeList<T>) { + assert!(list.pop().is_none(), "assertion failed: list is not empty"); +} + +#[test] +fn init_empty() { + unsafe { + assert_empty(&mut UnsafeList::<i32>::new()); + } +} + +#[test] +fn push_pop() { + unsafe { + let mut node = UnsafeListEntry::new(1234); + let mut list = UnsafeList::new(); + assert_eq!(list.push(&mut node), &1234); + assert_eq!(list.pop().unwrap(), &1234); + assert_empty(&mut list); + } +} + +#[test] +fn push_remove() { + unsafe { + let mut node = UnsafeListEntry::new(1234); + let mut list = UnsafeList::new(); + assert_eq!(list.push(&mut node), &1234); + list.remove(&mut node); + assert_empty(&mut list); + } +} + +#[test] +fn push_remove_pop() { + unsafe { + let mut node1 = UnsafeListEntry::new(11); + let mut node2 = UnsafeListEntry::new(12); + let mut node3 = UnsafeListEntry::new(13); + let mut node4 = UnsafeListEntry::new(14); + let mut node5 = UnsafeListEntry::new(15); + let mut list = UnsafeList::new(); + assert_eq!(list.push(&mut node1), &11); + assert_eq!(list.push(&mut node2), &12); + assert_eq!(list.push(&mut node3), &13); + assert_eq!(list.push(&mut node4), &14); + assert_eq!(list.push(&mut node5), &15); + + list.remove(&mut node1); + assert_eq!(list.pop().unwrap(), &12); + list.remove(&mut node3); + assert_eq!(list.pop().unwrap(), &14); + list.remove(&mut node5); + assert_empty(&mut list); + + assert_eq!(list.push(&mut node1), &11); + assert_eq!(list.pop().unwrap(), &11); + assert_empty(&mut list); + + assert_eq!(list.push(&mut node3), &13); + assert_eq!(list.push(&mut node4), &14); + list.remove(&mut node3); + list.remove(&mut node4); + assert_empty(&mut list); + } +} + +#[test] +fn complex_pushes_pops() { + unsafe { + let mut node1 = UnsafeListEntry::new(1234); + let mut node2 = UnsafeListEntry::new(4567); + let mut node3 = UnsafeListEntry::new(9999); + let mut node4 = UnsafeListEntry::new(8642); + let mut list = UnsafeList::new(); + list.push(&mut node1); + list.push(&mut node2); + assert_eq!(list.pop().unwrap(), &1234); + list.push(&mut node3); + assert_eq!(list.pop().unwrap(), &4567); + assert_eq!(list.pop().unwrap(), &9999); + assert_empty(&mut list); + list.push(&mut node4); + assert_eq!(list.pop().unwrap(), &8642); + assert_empty(&mut list); + } +} + +#[test] +fn cell() { + unsafe { + let mut node = UnsafeListEntry::new(Cell::new(0)); + let mut list = UnsafeList::new(); + let noderef = list.push(&mut node); + assert_eq!(noderef.get(), 0); + list.pop().unwrap().set(1); + assert_empty(&mut list); + assert_eq!(noderef.get(), 1); + } +} diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs index b590a0280d1..e48e950928a 100644 --- a/library/std/src/sys/unix/ext/fs.rs +++ b/library/std/src/sys/unix/ext/fs.rs @@ -8,6 +8,9 @@ use crate::path::Path; use crate::sys; use crate::sys::platform::fs::MetadataExt as UnixMetadataExt; use crate::sys_common::{AsInner, AsInnerMut, FromInner}; +// Used for `File::read` on intra-doc links +#[allow(unused_imports)] +use io::{Read, Write}; /// Unix-specific extensions to [`fs::File`]. #[stable(feature = "file_offset", since = "1.15.0")] @@ -24,7 +27,7 @@ pub trait FileExt { /// Note that similar to [`File::read`], it is not an error to return with a /// short read. /// - /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read + /// [`File::read`]: fs::File::read /// /// # Examples /// @@ -127,7 +130,7 @@ pub trait FileExt { /// Note that similar to [`File::write`], it is not an error to return a /// short write. /// - /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write + /// [`File::write`]: fs::File::write /// /// # Examples /// diff --git a/library/std/src/sys/unix/ext/net.rs b/library/std/src/sys/unix/ext/net.rs index 55803ddfc43..0e07106f5ce 100644 --- a/library/std/src/sys/unix/ext/net.rs +++ b/library/std/src/sys/unix/ext/net.rs @@ -2,6 +2,9 @@ //! Unix-specific networking functionality +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here? #[cfg(not(unix))] #[allow(non_camel_case_types)] @@ -1620,382 +1623,3 @@ impl IntoRawFd for UnixDatagram { self.0.into_inner() } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod test { - use crate::io::prelude::*; - use crate::io::{self, ErrorKind}; - use crate::sys_common::io::test::tmpdir; - use crate::thread; - use crate::time::Duration; - - use super::*; - - macro_rules! or_panic { - ($e:expr) => { - match $e { - Ok(e) => e, - Err(e) => panic!("{}", e), - } - }; - } - - #[test] - fn basic() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - let msg1 = b"hello"; - let msg2 = b"world!"; - - let listener = or_panic!(UnixListener::bind(&socket_path)); - let thread = thread::spawn(move || { - let mut stream = or_panic!(listener.accept()).0; - let mut buf = [0; 5]; - or_panic!(stream.read(&mut buf)); - assert_eq!(&msg1[..], &buf[..]); - or_panic!(stream.write_all(msg2)); - }); - - let mut stream = or_panic!(UnixStream::connect(&socket_path)); - assert_eq!(Some(&*socket_path), stream.peer_addr().unwrap().as_pathname()); - or_panic!(stream.write_all(msg1)); - let mut buf = vec![]; - or_panic!(stream.read_to_end(&mut buf)); - assert_eq!(&msg2[..], &buf[..]); - drop(stream); - - thread.join().unwrap(); - } - - #[test] - fn vectored() { - let (mut s1, mut s2) = or_panic!(UnixStream::pair()); - - let len = or_panic!(s1.write_vectored(&[ - IoSlice::new(b"hello"), - IoSlice::new(b" "), - IoSlice::new(b"world!") - ],)); - assert_eq!(len, 12); - - let mut buf1 = [0; 6]; - let mut buf2 = [0; 7]; - let len = or_panic!( - s2.read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) - ); - assert_eq!(len, 12); - assert_eq!(&buf1, b"hello "); - assert_eq!(&buf2, b"world!\0"); - } - - #[test] - fn pair() { - let msg1 = b"hello"; - let msg2 = b"world!"; - - let (mut s1, mut s2) = or_panic!(UnixStream::pair()); - let thread = thread::spawn(move || { - // s1 must be moved in or the test will hang! - let mut buf = [0; 5]; - or_panic!(s1.read(&mut buf)); - assert_eq!(&msg1[..], &buf[..]); - or_panic!(s1.write_all(msg2)); - }); - - or_panic!(s2.write_all(msg1)); - let mut buf = vec![]; - or_panic!(s2.read_to_end(&mut buf)); - assert_eq!(&msg2[..], &buf[..]); - drop(s2); - - thread.join().unwrap(); - } - - #[test] - fn try_clone() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - let msg1 = b"hello"; - let msg2 = b"world"; - - let listener = or_panic!(UnixListener::bind(&socket_path)); - let thread = thread::spawn(move || { - let mut stream = or_panic!(listener.accept()).0; - or_panic!(stream.write_all(msg1)); - or_panic!(stream.write_all(msg2)); - }); - - let mut stream = or_panic!(UnixStream::connect(&socket_path)); - let mut stream2 = or_panic!(stream.try_clone()); - - let mut buf = [0; 5]; - or_panic!(stream.read(&mut buf)); - assert_eq!(&msg1[..], &buf[..]); - or_panic!(stream2.read(&mut buf)); - assert_eq!(&msg2[..], &buf[..]); - - thread.join().unwrap(); - } - - #[test] - fn iter() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - - let listener = or_panic!(UnixListener::bind(&socket_path)); - let thread = thread::spawn(move || { - for stream in listener.incoming().take(2) { - let mut stream = or_panic!(stream); - let mut buf = [0]; - or_panic!(stream.read(&mut buf)); - } - }); - - for _ in 0..2 { - let mut stream = or_panic!(UnixStream::connect(&socket_path)); - or_panic!(stream.write_all(&[0])); - } - - thread.join().unwrap(); - } - - #[test] - fn long_path() { - let dir = tmpdir(); - let socket_path = dir.path().join( - "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\ - sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf", - ); - match UnixStream::connect(&socket_path) { - Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} - Err(e) => panic!("unexpected error {}", e), - Ok(_) => panic!("unexpected success"), - } - - match UnixListener::bind(&socket_path) { - Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} - Err(e) => panic!("unexpected error {}", e), - Ok(_) => panic!("unexpected success"), - } - - match UnixDatagram::bind(&socket_path) { - Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} - Err(e) => panic!("unexpected error {}", e), - Ok(_) => panic!("unexpected success"), - } - } - - #[test] - fn timeouts() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - - let _listener = or_panic!(UnixListener::bind(&socket_path)); - - let stream = or_panic!(UnixStream::connect(&socket_path)); - let dur = Duration::new(15410, 0); - - assert_eq!(None, or_panic!(stream.read_timeout())); - - or_panic!(stream.set_read_timeout(Some(dur))); - assert_eq!(Some(dur), or_panic!(stream.read_timeout())); - - assert_eq!(None, or_panic!(stream.write_timeout())); - - or_panic!(stream.set_write_timeout(Some(dur))); - assert_eq!(Some(dur), or_panic!(stream.write_timeout())); - - or_panic!(stream.set_read_timeout(None)); - assert_eq!(None, or_panic!(stream.read_timeout())); - - or_panic!(stream.set_write_timeout(None)); - assert_eq!(None, or_panic!(stream.write_timeout())); - } - - #[test] - fn test_read_timeout() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - - let _listener = or_panic!(UnixListener::bind(&socket_path)); - - let mut stream = or_panic!(UnixStream::connect(&socket_path)); - or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); - - let mut buf = [0; 10]; - let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); - assert!( - kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, - "unexpected_error: {:?}", - kind - ); - } - - #[test] - fn test_read_with_timeout() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - - let listener = or_panic!(UnixListener::bind(&socket_path)); - - let mut stream = or_panic!(UnixStream::connect(&socket_path)); - or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); - - let mut other_end = or_panic!(listener.accept()).0; - or_panic!(other_end.write_all(b"hello world")); - - let mut buf = [0; 11]; - or_panic!(stream.read(&mut buf)); - assert_eq!(b"hello world", &buf[..]); - - let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); - assert!( - kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, - "unexpected_error: {:?}", - kind - ); - } - - // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors - // when passed zero Durations - #[test] - fn test_unix_stream_timeout_zero_duration() { - let dir = tmpdir(); - let socket_path = dir.path().join("sock"); - - let listener = or_panic!(UnixListener::bind(&socket_path)); - let stream = or_panic!(UnixStream::connect(&socket_path)); - - let result = stream.set_write_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - - let result = stream.set_read_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - - drop(listener); - } - - #[test] - fn test_unix_datagram() { - let dir = tmpdir(); - let path1 = dir.path().join("sock1"); - let path2 = dir.path().join("sock2"); - - let sock1 = or_panic!(UnixDatagram::bind(&path1)); - let sock2 = or_panic!(UnixDatagram::bind(&path2)); - - let msg = b"hello world"; - or_panic!(sock1.send_to(msg, &path2)); - let mut buf = [0; 11]; - or_panic!(sock2.recv_from(&mut buf)); - assert_eq!(msg, &buf[..]); - } - - #[test] - fn test_unnamed_unix_datagram() { - let dir = tmpdir(); - let path1 = dir.path().join("sock1"); - - let sock1 = or_panic!(UnixDatagram::bind(&path1)); - let sock2 = or_panic!(UnixDatagram::unbound()); - - let msg = b"hello world"; - or_panic!(sock2.send_to(msg, &path1)); - let mut buf = [0; 11]; - let (usize, addr) = or_panic!(sock1.recv_from(&mut buf)); - assert_eq!(usize, 11); - assert!(addr.is_unnamed()); - assert_eq!(msg, &buf[..]); - } - - #[test] - fn test_connect_unix_datagram() { - let dir = tmpdir(); - let path1 = dir.path().join("sock1"); - let path2 = dir.path().join("sock2"); - - let bsock1 = or_panic!(UnixDatagram::bind(&path1)); - let bsock2 = or_panic!(UnixDatagram::bind(&path2)); - let sock = or_panic!(UnixDatagram::unbound()); - or_panic!(sock.connect(&path1)); - - // Check send() - let msg = b"hello there"; - or_panic!(sock.send(msg)); - let mut buf = [0; 11]; - let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf)); - assert_eq!(usize, 11); - assert!(addr.is_unnamed()); - assert_eq!(msg, &buf[..]); - - // Changing default socket works too - or_panic!(sock.connect(&path2)); - or_panic!(sock.send(msg)); - or_panic!(bsock2.recv_from(&mut buf)); - } - - #[test] - fn test_unix_datagram_recv() { - let dir = tmpdir(); - let path1 = dir.path().join("sock1"); - - let sock1 = or_panic!(UnixDatagram::bind(&path1)); - let sock2 = or_panic!(UnixDatagram::unbound()); - or_panic!(sock2.connect(&path1)); - - let msg = b"hello world"; - or_panic!(sock2.send(msg)); - let mut buf = [0; 11]; - let size = or_panic!(sock1.recv(&mut buf)); - assert_eq!(size, 11); - assert_eq!(msg, &buf[..]); - } - - #[test] - fn datagram_pair() { - let msg1 = b"hello"; - let msg2 = b"world!"; - - let (s1, s2) = or_panic!(UnixDatagram::pair()); - let thread = thread::spawn(move || { - // s1 must be moved in or the test will hang! - let mut buf = [0; 5]; - or_panic!(s1.recv(&mut buf)); - assert_eq!(&msg1[..], &buf[..]); - or_panic!(s1.send(msg2)); - }); - - or_panic!(s2.send(msg1)); - let mut buf = [0; 6]; - or_panic!(s2.recv(&mut buf)); - assert_eq!(&msg2[..], &buf[..]); - drop(s2); - - thread.join().unwrap(); - } - - // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors - // when passed zero Durations - #[test] - fn test_unix_datagram_timeout_zero_duration() { - let dir = tmpdir(); - let path = dir.path().join("sock"); - - let datagram = or_panic!(UnixDatagram::bind(&path)); - - let result = datagram.set_write_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - - let result = datagram.set_read_timeout(Some(Duration::new(0, 0))); - let err = result.unwrap_err(); - assert_eq!(err.kind(), ErrorKind::InvalidInput); - } - - #[test] - fn abstract_namespace_not_allowed() { - assert!(UnixStream::connect("\0asdf").is_err()); - } -} diff --git a/library/std/src/sys/unix/ext/net/tests.rs b/library/std/src/sys/unix/ext/net/tests.rs new file mode 100644 index 00000000000..be98766f0f3 --- /dev/null +++ b/library/std/src/sys/unix/ext/net/tests.rs @@ -0,0 +1,374 @@ +use crate::io::prelude::*; +use crate::io::{self, ErrorKind}; +use crate::sys_common::io::test::tmpdir; +use crate::thread; +use crate::time::Duration; + +use super::*; + +macro_rules! or_panic { + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{}", e), + } + }; +} + +#[test] +fn basic() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + let msg1 = b"hello"; + let msg2 = b"world!"; + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let thread = thread::spawn(move || { + let mut stream = or_panic!(listener.accept()).0; + let mut buf = [0; 5]; + or_panic!(stream.read(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(stream.write_all(msg2)); + }); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + assert_eq!(Some(&*socket_path), stream.peer_addr().unwrap().as_pathname()); + or_panic!(stream.write_all(msg1)); + let mut buf = vec![]; + or_panic!(stream.read_to_end(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + drop(stream); + + thread.join().unwrap(); +} + +#[test] +fn vectored() { + let (mut s1, mut s2) = or_panic!(UnixStream::pair()); + + let len = or_panic!(s1.write_vectored(&[ + IoSlice::new(b"hello"), + IoSlice::new(b" "), + IoSlice::new(b"world!") + ],)); + assert_eq!(len, 12); + + let mut buf1 = [0; 6]; + let mut buf2 = [0; 7]; + let len = + or_panic!(s2.read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)); + assert_eq!(len, 12); + assert_eq!(&buf1, b"hello "); + assert_eq!(&buf2, b"world!\0"); +} + +#[test] +fn pair() { + let msg1 = b"hello"; + let msg2 = b"world!"; + + let (mut s1, mut s2) = or_panic!(UnixStream::pair()); + let thread = thread::spawn(move || { + // s1 must be moved in or the test will hang! + let mut buf = [0; 5]; + or_panic!(s1.read(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(s1.write_all(msg2)); + }); + + or_panic!(s2.write_all(msg1)); + let mut buf = vec![]; + or_panic!(s2.read_to_end(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + drop(s2); + + thread.join().unwrap(); +} + +#[test] +fn try_clone() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + let msg1 = b"hello"; + let msg2 = b"world"; + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let thread = thread::spawn(move || { + let mut stream = or_panic!(listener.accept()).0; + or_panic!(stream.write_all(msg1)); + or_panic!(stream.write_all(msg2)); + }); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + let mut stream2 = or_panic!(stream.try_clone()); + + let mut buf = [0; 5]; + or_panic!(stream.read(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(stream2.read(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + + thread.join().unwrap(); +} + +#[test] +fn iter() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let thread = thread::spawn(move || { + for stream in listener.incoming().take(2) { + let mut stream = or_panic!(stream); + let mut buf = [0]; + or_panic!(stream.read(&mut buf)); + } + }); + + for _ in 0..2 { + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + or_panic!(stream.write_all(&[0])); + } + + thread.join().unwrap(); +} + +#[test] +fn long_path() { + let dir = tmpdir(); + let socket_path = dir.path().join( + "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\ + sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf", + ); + match UnixStream::connect(&socket_path) { + Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} + Err(e) => panic!("unexpected error {}", e), + Ok(_) => panic!("unexpected success"), + } + + match UnixListener::bind(&socket_path) { + Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} + Err(e) => panic!("unexpected error {}", e), + Ok(_) => panic!("unexpected success"), + } + + match UnixDatagram::bind(&socket_path) { + Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} + Err(e) => panic!("unexpected error {}", e), + Ok(_) => panic!("unexpected success"), + } +} + +#[test] +fn timeouts() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let _listener = or_panic!(UnixListener::bind(&socket_path)); + + let stream = or_panic!(UnixStream::connect(&socket_path)); + let dur = Duration::new(15410, 0); + + assert_eq!(None, or_panic!(stream.read_timeout())); + + or_panic!(stream.set_read_timeout(Some(dur))); + assert_eq!(Some(dur), or_panic!(stream.read_timeout())); + + assert_eq!(None, or_panic!(stream.write_timeout())); + + or_panic!(stream.set_write_timeout(Some(dur))); + assert_eq!(Some(dur), or_panic!(stream.write_timeout())); + + or_panic!(stream.set_read_timeout(None)); + assert_eq!(None, or_panic!(stream.read_timeout())); + + or_panic!(stream.set_write_timeout(None)); + assert_eq!(None, or_panic!(stream.write_timeout())); +} + +#[test] +fn test_read_timeout() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let _listener = or_panic!(UnixListener::bind(&socket_path)); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut buf = [0; 10]; + let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); + assert!( + kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", + kind + ); +} + +#[test] +fn test_read_with_timeout() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let listener = or_panic!(UnixListener::bind(&socket_path)); + + let mut stream = or_panic!(UnixStream::connect(&socket_path)); + or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); + + let mut other_end = or_panic!(listener.accept()).0; + or_panic!(other_end.write_all(b"hello world")); + + let mut buf = [0; 11]; + or_panic!(stream.read(&mut buf)); + assert_eq!(b"hello world", &buf[..]); + + let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); + assert!( + kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, + "unexpected_error: {:?}", + kind + ); +} + +// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors +// when passed zero Durations +#[test] +fn test_unix_stream_timeout_zero_duration() { + let dir = tmpdir(); + let socket_path = dir.path().join("sock"); + + let listener = or_panic!(UnixListener::bind(&socket_path)); + let stream = or_panic!(UnixStream::connect(&socket_path)); + + let result = stream.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = stream.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + drop(listener); +} + +#[test] +fn test_unix_datagram() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + let path2 = dir.path().join("sock2"); + + let sock1 = or_panic!(UnixDatagram::bind(&path1)); + let sock2 = or_panic!(UnixDatagram::bind(&path2)); + + let msg = b"hello world"; + or_panic!(sock1.send_to(msg, &path2)); + let mut buf = [0; 11]; + or_panic!(sock2.recv_from(&mut buf)); + assert_eq!(msg, &buf[..]); +} + +#[test] +fn test_unnamed_unix_datagram() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + + let sock1 = or_panic!(UnixDatagram::bind(&path1)); + let sock2 = or_panic!(UnixDatagram::unbound()); + + let msg = b"hello world"; + or_panic!(sock2.send_to(msg, &path1)); + let mut buf = [0; 11]; + let (usize, addr) = or_panic!(sock1.recv_from(&mut buf)); + assert_eq!(usize, 11); + assert!(addr.is_unnamed()); + assert_eq!(msg, &buf[..]); +} + +#[test] +fn test_connect_unix_datagram() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + let path2 = dir.path().join("sock2"); + + let bsock1 = or_panic!(UnixDatagram::bind(&path1)); + let bsock2 = or_panic!(UnixDatagram::bind(&path2)); + let sock = or_panic!(UnixDatagram::unbound()); + or_panic!(sock.connect(&path1)); + + // Check send() + let msg = b"hello there"; + or_panic!(sock.send(msg)); + let mut buf = [0; 11]; + let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf)); + assert_eq!(usize, 11); + assert!(addr.is_unnamed()); + assert_eq!(msg, &buf[..]); + + // Changing default socket works too + or_panic!(sock.connect(&path2)); + or_panic!(sock.send(msg)); + or_panic!(bsock2.recv_from(&mut buf)); +} + +#[test] +fn test_unix_datagram_recv() { + let dir = tmpdir(); + let path1 = dir.path().join("sock1"); + + let sock1 = or_panic!(UnixDatagram::bind(&path1)); + let sock2 = or_panic!(UnixDatagram::unbound()); + or_panic!(sock2.connect(&path1)); + + let msg = b"hello world"; + or_panic!(sock2.send(msg)); + let mut buf = [0; 11]; + let size = or_panic!(sock1.recv(&mut buf)); + assert_eq!(size, 11); + assert_eq!(msg, &buf[..]); +} + +#[test] +fn datagram_pair() { + let msg1 = b"hello"; + let msg2 = b"world!"; + + let (s1, s2) = or_panic!(UnixDatagram::pair()); + let thread = thread::spawn(move || { + // s1 must be moved in or the test will hang! + let mut buf = [0; 5]; + or_panic!(s1.recv(&mut buf)); + assert_eq!(&msg1[..], &buf[..]); + or_panic!(s1.send(msg2)); + }); + + or_panic!(s2.send(msg1)); + let mut buf = [0; 6]; + or_panic!(s2.recv(&mut buf)); + assert_eq!(&msg2[..], &buf[..]); + drop(s2); + + thread.join().unwrap(); +} + +// Ensure the `set_read_timeout` and `set_write_timeout` calls return errors +// when passed zero Durations +#[test] +fn test_unix_datagram_timeout_zero_duration() { + let dir = tmpdir(); + let path = dir.path().join("sock"); + + let datagram = or_panic!(UnixDatagram::bind(&path)); + + let result = datagram.set_write_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); + + let result = datagram.set_read_timeout(Some(Duration::new(0, 0))); + let err = result.unwrap_err(); + assert_eq!(err.kind(), ErrorKind::InvalidInput); +} + +#[test] +fn abstract_namespace_not_allowed() { + assert!(UnixStream::connect("\0asdf").is_err()); +} diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index ba169b251b0..b2f15eda9d7 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -1,5 +1,8 @@ #![unstable(reason = "not public", issue = "none", feature = "fd")] +#[cfg(test)] +mod tests; + use crate::cmp; use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read}; use crate::mem; @@ -279,16 +282,3 @@ impl Drop for FileDesc { let _ = unsafe { libc::close(self.fd) }; } } - -#[cfg(test)] -mod tests { - use super::{FileDesc, IoSlice}; - use core::mem::ManuallyDrop; - - #[test] - fn limit_vector_count() { - let stdout = ManuallyDrop::new(FileDesc { fd: 1 }); - let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>(); - assert!(stdout.write_vectored(&bufs).is_ok()); - } -} diff --git a/library/std/src/sys/unix/fd/tests.rs b/library/std/src/sys/unix/fd/tests.rs new file mode 100644 index 00000000000..a932043cbc6 --- /dev/null +++ b/library/std/src/sys/unix/fd/tests.rs @@ -0,0 +1,9 @@ +use super::{FileDesc, IoSlice}; +use core::mem::ManuallyDrop; + +#[test] +fn limit_vector_count() { + let stdout = ManuallyDrop::new(FileDesc { fd: 1 }); + let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>(); + assert!(stdout.write_vectored(&bufs).is_ok()); +} diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 2fcb5b9c4e6..4aa61fc5bf6 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -2,6 +2,9 @@ #![allow(unused_imports)] // lots of cfg code here +#[cfg(all(test, target_env = "gnu"))] +mod tests; + use crate::os::unix::prelude::*; use crate::error::Error as StdError; @@ -645,30 +648,3 @@ fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { _ => None, } } - -#[cfg(all(test, target_env = "gnu"))] -mod test { - use super::*; - - #[test] - fn test_glibc_version() { - // This mostly just tests that the weak linkage doesn't panic wildly... - glibc_version(); - } - - #[test] - fn test_parse_glibc_version() { - let cases = [ - ("0.0", Some((0, 0))), - ("01.+2", Some((1, 2))), - ("3.4.5.six", Some((3, 4))), - ("1", None), - ("1.-2", None), - ("1.foo", None), - ("foo.1", None), - ]; - for &(version_str, parsed) in cases.iter() { - assert_eq!(parsed, parse_glibc_version(version_str)); - } - } -} diff --git a/library/std/src/sys/unix/os/tests.rs b/library/std/src/sys/unix/os/tests.rs new file mode 100644 index 00000000000..0e1dcb390a0 --- /dev/null +++ b/library/std/src/sys/unix/os/tests.rs @@ -0,0 +1,23 @@ +use super::*; + +#[test] +fn test_glibc_version() { + // This mostly just tests that the weak linkage doesn't panic wildly... + glibc_version(); +} + +#[test] +fn test_parse_glibc_version() { + let cases = [ + ("0.0", Some((0, 0))), + ("01.+2", Some((1, 2))), + ("3.4.5.six", Some((3, 4))), + ("1", None), + ("1.-2", None), + ("1.foo", None), + ("foo.1", None), + ]; + for &(version_str, parsed) in cases.iter() { + assert_eq!(parsed, parse_glibc_version(version_str)); + } +} diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 6e33cdd3c48..f8666485eec 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::os::unix::prelude::*; use crate::collections::BTreeMap; @@ -399,71 +402,3 @@ impl ExitCode { self.0 as i32 } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use super::*; - - use crate::ffi::OsStr; - use crate::mem; - use crate::ptr; - use crate::sys::cvt; - - macro_rules! t { - ($e:expr) => { - match $e { - Ok(t) => t, - Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), - } - }; - } - - // See #14232 for more information, but it appears that signal delivery to a - // newly spawned process may just be raced in the macOS, so to prevent this - // test from being flaky we ignore it on macOS. - #[test] - #[cfg_attr(target_os = "macos", ignore)] - // When run under our current QEMU emulation test suite this test fails, - // although the reason isn't very clear as to why. For now this test is - // ignored there. - #[cfg_attr(target_arch = "arm", ignore)] - #[cfg_attr(target_arch = "aarch64", ignore)] - #[cfg_attr(target_arch = "riscv64", ignore)] - fn test_process_mask() { - unsafe { - // Test to make sure that a signal mask does not get inherited. - let mut cmd = Command::new(OsStr::new("cat")); - - let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit(); - let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit(); - t!(cvt(sigemptyset(set.as_mut_ptr()))); - t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT))); - t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr()))); - - cmd.stdin(Stdio::MakePipe); - cmd.stdout(Stdio::MakePipe); - - let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true)); - let stdin_write = pipes.stdin.take().unwrap(); - let stdout_read = pipes.stdout.take().unwrap(); - - t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut()))); - - t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT))); - // We need to wait until SIGINT is definitely delivered. The - // easiest way is to write something to cat, and try to read it - // back: if SIGINT is unmasked, it'll get delivered when cat is - // next scheduled. - let _ = stdin_write.write(b"Hello"); - drop(stdin_write); - - // Either EOF or failure (EPIPE) is okay. - let mut buf = [0; 5]; - if let Ok(ret) = stdout_read.read(&mut buf) { - assert_eq!(ret, 0); - } - - t!(cat.wait()); - } - } -} diff --git a/library/std/src/sys/unix/process/process_common/tests.rs b/library/std/src/sys/unix/process/process_common/tests.rs new file mode 100644 index 00000000000..e72fbf0beb4 --- /dev/null +++ b/library/std/src/sys/unix/process/process_common/tests.rs @@ -0,0 +1,64 @@ +use super::*; + +use crate::ffi::OsStr; +use crate::mem; +use crate::ptr; +use crate::sys::cvt; + +macro_rules! t { + ($e:expr) => { + match $e { + Ok(t) => t, + Err(e) => panic!("received error for `{}`: {}", stringify!($e), e), + } + }; +} + +// See #14232 for more information, but it appears that signal delivery to a +// newly spawned process may just be raced in the macOS, so to prevent this +// test from being flaky we ignore it on macOS. +#[test] +#[cfg_attr(target_os = "macos", ignore)] +// When run under our current QEMU emulation test suite this test fails, +// although the reason isn't very clear as to why. For now this test is +// ignored there. +#[cfg_attr(target_arch = "arm", ignore)] +#[cfg_attr(target_arch = "aarch64", ignore)] +#[cfg_attr(target_arch = "riscv64", ignore)] +fn test_process_mask() { + unsafe { + // Test to make sure that a signal mask does not get inherited. + let mut cmd = Command::new(OsStr::new("cat")); + + let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit(); + let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit(); + t!(cvt(sigemptyset(set.as_mut_ptr()))); + t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT))); + t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr()))); + + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + + let (mut cat, mut pipes) = t!(cmd.spawn(Stdio::Null, true)); + let stdin_write = pipes.stdin.take().unwrap(); + let stdout_read = pipes.stdout.take().unwrap(); + + t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(), ptr::null_mut()))); + + t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT))); + // We need to wait until SIGINT is definitely delivered. The + // easiest way is to write something to cat, and try to read it + // back: if SIGINT is unmasked, it'll get delivered when cat is + // next scheduled. + let _ = stdin_write.write(b"Hello"); + drop(stdin_write); + + // Either EOF or failure (EPIPE) is okay. + let mut buf = [0; 5]; + if let Ok(ret) = stdout_read.read(&mut buf) { + assert_eq!(ret, 0); + } + + t!(cat.wait()); + } +} diff --git a/library/std/src/sys/vxworks/net.rs b/library/std/src/sys/vxworks/net.rs index 32c27ab6e9e..7613fbec46f 100644 --- a/library/std/src/sys/vxworks/net.rs +++ b/library/std/src/sys/vxworks/net.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, taget_env = "gnu"))] +mod tests; + use crate::cmp; use crate::ffi::CStr; use crate::io; @@ -330,30 +333,3 @@ fn on_resolver_failure() { #[cfg(not(target_env = "gnu"))] fn on_resolver_failure() {} - -#[cfg(all(test, taget_env = "gnu"))] -mod test { - use super::*; - - #[test] - fn test_res_init() { - // This mostly just tests that the weak linkage doesn't panic wildly... - res_init_if_glibc_before_2_26().unwrap(); - } - - #[test] - fn test_parse_glibc_version() { - let cases = [ - ("0.0", Some((0, 0))), - ("01.+2", Some((1, 2))), - ("3.4.5.six", Some((3, 4))), - ("1", None), - ("1.-2", None), - ("1.foo", None), - ("foo.1", None), - ]; - for &(version_str, parsed) in cases.iter() { - assert_eq!(parsed, parse_glibc_version(version_str)); - } - } -} diff --git a/library/std/src/sys/vxworks/net/tests.rs b/library/std/src/sys/vxworks/net/tests.rs new file mode 100644 index 00000000000..e7c6e348f8e --- /dev/null +++ b/library/std/src/sys/vxworks/net/tests.rs @@ -0,0 +1,23 @@ +use super::*; + +#[test] +fn test_res_init() { + // This mostly just tests that the weak linkage doesn't panic wildly... + res_init_if_glibc_before_2_26().unwrap(); +} + +#[test] +fn test_parse_glibc_version() { + let cases = [ + ("0.0", Some((0, 0))), + ("01.+2", Some((1, 2))), + ("3.4.5.six", Some((3, 4))), + ("1", None), + ("1.-2", None), + ("1.foo", None), + ("foo.1", None), + ]; + for &(version_str, parsed) in cases.iter() { + assert_eq!(parsed, parse_glibc_version(version_str)); + } +} diff --git a/library/std/src/sys/wasi/alloc.rs b/library/std/src/sys/wasi/alloc.rs index 57187851a14..4d0afe27bb8 100644 --- a/library/std/src/sys/wasi/alloc.rs +++ b/library/std/src/sys/wasi/alloc.rs @@ -1,26 +1,45 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN}; +// SAFETY: All methods implemented follow the contract rules defined +// in `GlobalAlloc`. #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut u8 + // SAFETY: `libc::malloc` is guaranteed to be safe, it will allocate + // `layout.size()` bytes of memory and return a pointer to it + unsafe { libc::malloc(layout.size()) as *mut u8 } } else { - libc::aligned_alloc(layout.align(), layout.size()) as *mut u8 + // SAFETY: `libc::aligned_alloc` is guaranteed to be safe if + // `layout.size()` is a multiple of `layout.align()`. This + // constraint can be satisfied if `pad_to_align` is called, + // which creates a layout by rounding the size of this layout up + // to a multiple of the layout's alignment + let aligned_layout = layout.pad_to_align(); + unsafe { libc::aligned_alloc(aligned_layout.align(), aligned_layout.size()) as *mut u8 } } } #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::calloc(layout.size(), 1) as *mut u8 + // SAFETY: `libc::calloc` is safe as long that `layout.size() * 1` + // would not result in integer overflow which cannot happen, + // multiplying by one never overflows + unsafe { libc::calloc(layout.size(), 1) as *mut u8 } } else { - let ptr = self.alloc(layout.clone()); + // SAFETY: The safety contract for `alloc` must be upheld by the caller + let ptr = unsafe { self.alloc(layout.clone()) }; if !ptr.is_null() { - ptr::write_bytes(ptr, 0, layout.size()); + // SAFETY: in the case of the `ptr` being not null + // it will be properly aligned and a valid ptr + // which satisfies `ptr::write_bytes` safety constrains + unsafe { ptr::write_bytes(ptr, 0, layout.size()) }; } ptr } @@ -28,15 +47,23 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - libc::free(ptr as *mut libc::c_void) + // SAFETY: `libc::free` is guaranteed to be safe if `ptr` is allocated + // by this allocator or if `ptr` is NULL + unsafe { libc::free(ptr as *mut libc::c_void) } } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= new_size { - libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 + // SAFETY: `libc::realloc` is safe if `ptr` is allocated by this + // allocator or NULL + // - If `new_size` is 0 and `ptr` is not NULL, it will act as `libc::free` + // - If `new_size` is not 0 and `ptr` is NULL, it will act as `libc::malloc` + // - Else, it will resize the block accordingly + unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } } else { - realloc_fallback(self, ptr, layout, new_size) + // SAFETY: The safety contract for `realloc_fallback` must be upheld by the caller + unsafe { realloc_fallback(self, ptr, layout, new_size) } } } } diff --git a/library/std/src/sys/wasi/args.rs b/library/std/src/sys/wasi/args.rs index 02aa68d6f3a..9a27218e1fb 100644 --- a/library/std/src/sys/wasi/args.rs +++ b/library/std/src/sys/wasi/args.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::{CStr, OsStr, OsString}; use crate::marker::PhantomData; use crate::os::wasi::ffi::OsStrExt; diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 501ad8ee7d6..4f7cf6018d9 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -1,5 +1,6 @@ //! WASI-specific extensions to primitives in the `std::fs` module. +#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "none")] use crate::fs::{self, File, Metadata, OpenOptions}; diff --git a/library/std/src/sys/wasi/ext/io.rs b/library/std/src/sys/wasi/ext/io.rs index e849400d67e..4e8fa65eb20 100644 --- a/library/std/src/sys/wasi/ext/io.rs +++ b/library/std/src/sys/wasi/ext/io.rs @@ -1,5 +1,6 @@ //! WASI-specific extensions to general I/O primitives +#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "none")] use crate::fs; diff --git a/library/std/src/sys/wasi/ext/mod.rs b/library/std/src/sys/wasi/ext/mod.rs index 58c8c46c969..1cda30edcad 100644 --- a/library/std/src/sys/wasi/ext/mod.rs +++ b/library/std/src/sys/wasi/ext/mod.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + pub mod ffi; pub mod fs; pub mod io; diff --git a/library/std/src/sys/wasi/fd.rs b/library/std/src/sys/wasi/fd.rs index 8458ded5db0..ba66eba2ad3 100644 --- a/library/std/src/sys/wasi/fd.rs +++ b/library/std/src/sys/wasi/fd.rs @@ -1,3 +1,4 @@ +#![deny(unsafe_op_in_unsafe_fn)] #![allow(dead_code)] use super::err2io; diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 8408756f1b3..93a92b49cfc 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; use crate::io::{self, IoSlice, IoSliceMut, SeekFrom}; diff --git a/library/std/src/sys/wasi/io.rs b/library/std/src/sys/wasi/io.rs index 0ad2e152855..ee017d13a4c 100644 --- a/library/std/src/sys/wasi/io.rs +++ b/library/std/src/sys/wasi/io.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::marker::PhantomData; use crate::slice; diff --git a/library/std/src/sys/wasi/net.rs b/library/std/src/sys/wasi/net.rs index e186453588d..8fd4bb76d85 100644 --- a/library/std/src/sys/wasi/net.rs +++ b/library/std/src/sys/wasi/net.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::convert::TryFrom; use crate::fmt; use crate::io::{self, IoSlice, IoSliceMut}; diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs index 8052c0aa8a8..33c796ae941 100644 --- a/library/std/src/sys/wasi/os.rs +++ b/library/std/src/sys/wasi/os.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::any::Any; use crate::error::Error as StdError; use crate::ffi::{CStr, CString, OsStr, OsString}; diff --git a/library/std/src/sys/wasi/pipe.rs b/library/std/src/sys/wasi/pipe.rs index 10d0925823e..180fc114d86 100644 --- a/library/std/src/sys/wasi/pipe.rs +++ b/library/std/src/sys/wasi/pipe.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::io::{self, IoSlice, IoSliceMut}; use crate::sys::Void; diff --git a/library/std/src/sys/wasi/process.rs b/library/std/src/sys/wasi/process.rs index 7156c9ab92f..c69d6376b01 100644 --- a/library/std/src/sys/wasi/process.rs +++ b/library/std/src/sys/wasi/process.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::OsStr; use crate::fmt; use crate::io; diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs index 23baafabf79..d82f6f41186 100644 --- a/library/std/src/sys/wasi/stdio.rs +++ b/library/std/src/sys/wasi/stdio.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::sys::fd::WasiFd; diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs index 0d39b1cec32..8eaa5f09cb6 100644 --- a/library/std/src/sys/wasi/thread.rs +++ b/library/std/src/sys/wasi/thread.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::CStr; use crate::io; use crate::mem; diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs index 80ec317b5a2..2e720d11603 100644 --- a/library/std/src/sys/wasi/time.rs +++ b/library/std/src/sys/wasi/time.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::time::Duration; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index 5fbea2a2910..bcc2ea9ae00 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -1,5 +1,8 @@ #![allow(dead_code)] // runtime init functions not used during testing +#[cfg(test)] +mod tests; + use crate::ffi::OsString; use crate::fmt; use crate::os::windows::prelude::*; @@ -198,69 +201,3 @@ impl ExactSizeIterator for Args { self.parsed_args_list.len() } } - -#[cfg(test)] -mod tests { - use crate::ffi::OsString; - use crate::sys::windows::args::*; - - fn chk(string: &str, parts: &[&str]) { - let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect(); - wide.push(0); - let parsed = unsafe { - parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE")) - }; - let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect(); - assert_eq!(parsed.as_slice(), expected.as_slice()); - } - - #[test] - fn empty() { - chk("", &["TEST.EXE"]); - chk("\0", &["TEST.EXE"]); - } - - #[test] - fn single_words() { - chk("EXE one_word", &["EXE", "one_word"]); - chk("EXE a", &["EXE", "a"]); - chk("EXE 😅", &["EXE", "😅"]); - chk("EXE 😅🤦", &["EXE", "😅🤦"]); - } - - #[test] - fn official_examples() { - chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]); - chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]); - chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]); - chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]); - } - - #[test] - fn whitespace_behavior() { - chk(r#" test"#, &["", "test"]); - chk(r#" test"#, &["", "test"]); - chk(r#" test test2"#, &["", "test", "test2"]); - chk(r#" test test2"#, &["", "test", "test2"]); - chk(r#"test test2 "#, &["test", "test2"]); - chk(r#"test test2 "#, &["test", "test2"]); - chk(r#"test "#, &["test"]); - } - - #[test] - fn genius_quotes() { - chk(r#"EXE "" """#, &["EXE", "", ""]); - chk(r#"EXE "" """"#, &["EXE", "", "\""]); - chk( - r#"EXE "this is """all""" in the same argument""#, - &["EXE", "this is \"all\" in the same argument"], - ); - chk(r#"EXE "a"""#, &["EXE", "a\""]); - chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]); - // quotes cannot be escaped in command names - chk(r#""EXE" check"#, &["EXE", "check"]); - chk(r#""EXE check""#, &["EXE check"]); - chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]); - chk(r#""EXE \"for\" check"#, &[r#"EXE \"#, r#"for""#, "check"]); - } -} diff --git a/library/std/src/sys/windows/args/tests.rs b/library/std/src/sys/windows/args/tests.rs new file mode 100644 index 00000000000..756a4361ea3 --- /dev/null +++ b/library/std/src/sys/windows/args/tests.rs @@ -0,0 +1,61 @@ +use crate::ffi::OsString; +use crate::sys::windows::args::*; + +fn chk(string: &str, parts: &[&str]) { + let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect(); + wide.push(0); + let parsed = + unsafe { parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE")) }; + let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect(); + assert_eq!(parsed.as_slice(), expected.as_slice()); +} + +#[test] +fn empty() { + chk("", &["TEST.EXE"]); + chk("\0", &["TEST.EXE"]); +} + +#[test] +fn single_words() { + chk("EXE one_word", &["EXE", "one_word"]); + chk("EXE a", &["EXE", "a"]); + chk("EXE 😅", &["EXE", "😅"]); + chk("EXE 😅🤦", &["EXE", "😅🤦"]); +} + +#[test] +fn official_examples() { + chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]); + chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]); + chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]); + chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]); +} + +#[test] +fn whitespace_behavior() { + chk(r#" test"#, &["", "test"]); + chk(r#" test"#, &["", "test"]); + chk(r#" test test2"#, &["", "test", "test2"]); + chk(r#" test test2"#, &["", "test", "test2"]); + chk(r#"test test2 "#, &["test", "test2"]); + chk(r#"test test2 "#, &["test", "test2"]); + chk(r#"test "#, &["test"]); +} + +#[test] +fn genius_quotes() { + chk(r#"EXE "" """#, &["EXE", "", ""]); + chk(r#"EXE "" """"#, &["EXE", "", "\""]); + chk( + r#"EXE "this is """all""" in the same argument""#, + &["EXE", "this is \"all\" in the same argument"], + ); + chk(r#"EXE "a"""#, &["EXE", "a\""]); + chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]); + // quotes cannot be escaped in command names + chk(r#""EXE" check"#, &["EXE", "check"]); + chk(r#""EXE check""#, &["EXE check"]); + chk(r#""EXE """for""" check"#, &["EXE ", r#"for""#, "check"]); + chk(r#""EXE \"for\" check"#, &[r#"EXE \"#, r#"for""#, "check"]); +} diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs index a0da2498bb7..77c378a66af 100644 --- a/library/std/src/sys/windows/os.rs +++ b/library/std/src/sys/windows/os.rs @@ -2,6 +2,9 @@ #![allow(nonstandard_style)] +#[cfg(test)] +mod tests; + use crate::os::windows::prelude::*; use crate::error::Error as StdError; @@ -328,20 +331,3 @@ pub fn exit(code: i32) -> ! { pub fn getpid() -> u32 { unsafe { c::GetCurrentProcessId() as u32 } } - -#[cfg(test)] -mod tests { - use crate::io::Error; - use crate::sys::c; - - // tests `error_string` above - #[test] - fn ntstatus_error() { - const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001; - assert!( - !Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _) - .to_string() - .contains("FormatMessageW() returned error") - ); - } -} diff --git a/library/std/src/sys/windows/os/tests.rs b/library/std/src/sys/windows/os/tests.rs new file mode 100644 index 00000000000..458d6e11c20 --- /dev/null +++ b/library/std/src/sys/windows/os/tests.rs @@ -0,0 +1,13 @@ +use crate::io::Error; +use crate::sys::c; + +// tests `error_string` above +#[test] +fn ntstatus_error() { + const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001; + assert!( + !Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _) + .to_string() + .contains("FormatMessageW() returned error") + ); +} diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 7d6d4775eec..e18521bb30d 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -1,5 +1,8 @@ #![unstable(feature = "process_internals", issue = "none")] +#[cfg(test)] +mod tests; + use crate::borrow::Borrow; use crate::collections::BTreeMap; use crate::env; @@ -526,41 +529,3 @@ fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> { None => Ok((ptr::null(), Vec::new())), } } - -#[cfg(test)] -mod tests { - use super::make_command_line; - use crate::ffi::{OsStr, OsString}; - - #[test] - fn test_make_command_line() { - fn test_wrapper(prog: &str, args: &[&str]) -> String { - let command_line = &make_command_line( - OsStr::new(prog), - &args.iter().map(|a| OsString::from(a)).collect::<Vec<OsString>>(), - ) - .unwrap(); - String::from_utf16(command_line).unwrap() - } - - assert_eq!(test_wrapper("prog", &["aaa", "bbb", "ccc"]), "\"prog\" aaa bbb ccc"); - - assert_eq!( - test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]), - "\"C:\\Program Files\\blah\\blah.exe\" aaa" - ); - assert_eq!( - test_wrapper("C:\\Program Files\\test", &["aa\"bb"]), - "\"C:\\Program Files\\test\" aa\\\"bb" - ); - assert_eq!(test_wrapper("echo", &["a b c"]), "\"echo\" \"a b c\""); - assert_eq!( - test_wrapper("echo", &["\" \\\" \\", "\\"]), - "\"echo\" \"\\\" \\\\\\\" \\\\\" \\" - ); - assert_eq!( - test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]), - "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\"" - ); - } -} diff --git a/library/std/src/sys/windows/process/tests.rs b/library/std/src/sys/windows/process/tests.rs new file mode 100644 index 00000000000..81627ad139b --- /dev/null +++ b/library/std/src/sys/windows/process/tests.rs @@ -0,0 +1,31 @@ +use super::make_command_line; +use crate::ffi::{OsStr, OsString}; + +#[test] +fn test_make_command_line() { + fn test_wrapper(prog: &str, args: &[&str]) -> String { + let command_line = &make_command_line( + OsStr::new(prog), + &args.iter().map(|a| OsString::from(a)).collect::<Vec<OsString>>(), + ) + .unwrap(); + String::from_utf16(command_line).unwrap() + } + + assert_eq!(test_wrapper("prog", &["aaa", "bbb", "ccc"]), "\"prog\" aaa bbb ccc"); + + assert_eq!( + test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]), + "\"C:\\Program Files\\blah\\blah.exe\" aaa" + ); + assert_eq!( + test_wrapper("C:\\Program Files\\test", &["aa\"bb"]), + "\"C:\\Program Files\\test\" aa\\\"bb" + ); + assert_eq!(test_wrapper("echo", &["a b c"]), "\"echo\" \"a b c\""); + assert_eq!(test_wrapper("echo", &["\" \\\" \\", "\\"]), "\"echo\" \"\\\" \\\\\\\" \\\\\" \\"); + assert_eq!( + test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]), + "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\"" + ); +} diff --git a/library/std/src/sys_common/bytestring.rs b/library/std/src/sys_common/bytestring.rs index dccc3bc4a19..97fba60c271 100644 --- a/library/std/src/sys_common/bytestring.rs +++ b/library/std/src/sys_common/bytestring.rs @@ -1,5 +1,8 @@ #![allow(dead_code)] +#[cfg(test)] +mod tests; + use crate::fmt::{Formatter, Result, Write}; use core::str::lossy::{Utf8Lossy, Utf8LossyChunk}; @@ -21,26 +24,3 @@ pub fn debug_fmt_bytestring(slice: &[u8], f: &mut Formatter<'_>) -> Result { } f.write_str("\"") } - -#[cfg(test)] -mod tests { - use super::*; - use crate::fmt::{Debug, Formatter, Result}; - - #[test] - fn smoke() { - struct Helper<'a>(&'a [u8]); - - impl Debug for Helper<'_> { - fn fmt(&self, f: &mut Formatter<'_>) -> Result { - debug_fmt_bytestring(self.0, f) - } - } - - let input = b"\xF0hello,\tworld"; - let expected = r#""\xF0hello,\tworld""#; - let output = format!("{:?}", Helper(input)); - - assert!(output == expected); - } -} diff --git a/library/std/src/sys_common/bytestring/tests.rs b/library/std/src/sys_common/bytestring/tests.rs new file mode 100644 index 00000000000..1685f087d18 --- /dev/null +++ b/library/std/src/sys_common/bytestring/tests.rs @@ -0,0 +1,19 @@ +use super::*; +use crate::fmt::{Debug, Formatter, Result}; + +#[test] +fn smoke() { + struct Helper<'a>(&'a [u8]); + + impl Debug for Helper<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + debug_fmt_bytestring(self.0, f) + } + } + + let input = b"\xF0hello,\tworld"; + let expected = r#""\xF0hello,\tworld""#; + let output = format!("{:?}", Helper(input)); + + assert!(output == expected); +} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 840f9093e00..28cdfefb12a 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -15,6 +15,9 @@ #![allow(missing_docs)] #![allow(missing_debug_implementations)] +#[cfg(test)] +mod tests; + use crate::sync::Once; use crate::sys; @@ -141,8 +144,3 @@ pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { // r < denom, so (denom*numer) is the upper bound of (r*numer) q * numer + r * numer / denom } - -#[test] -fn test_muldiv() { - assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000); -} diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 0bb136078bc..48ba4ddfc0b 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::cmp; use crate::convert::{TryFrom, TryInto}; use crate::ffi::CString; @@ -672,26 +675,3 @@ impl fmt::Debug for UdpSocket { res.field(name, &self.inner.as_inner()).finish() } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::collections::HashMap; - - #[test] - fn no_lookup_host_duplicates() { - let mut addrs = HashMap::new(); - let lh = match LookupHost::try_from(("localhost", 0)) { - Ok(lh) => lh, - Err(e) => panic!("couldn't resolve `localhost': {}", e), - }; - for sa in lh { - *addrs.entry(sa).or_insert(0) += 1; - } - assert_eq!( - addrs.iter().filter(|&(_, &v)| v > 1).collect::<Vec<_>>(), - vec![], - "There should be no duplicate localhost entries" - ); - } -} diff --git a/library/std/src/sys_common/net/tests.rs b/library/std/src/sys_common/net/tests.rs new file mode 100644 index 00000000000..7d45621e09a --- /dev/null +++ b/library/std/src/sys_common/net/tests.rs @@ -0,0 +1,19 @@ +use super::*; +use crate::collections::HashMap; + +#[test] +fn no_lookup_host_duplicates() { + let mut addrs = HashMap::new(); + let lh = match LookupHost::try_from(("localhost", 0)) { + Ok(lh) => lh, + Err(e) => panic!("couldn't resolve `localhost': {}", e), + }; + for sa in lh { + *addrs.entry(sa).or_insert(0) += 1; + } + assert_eq!( + addrs.iter().filter(|&(_, &v)| v > 1).collect::<Vec<_>>(), + vec![], + "There should be no duplicate localhost entries" + ); +} diff --git a/library/std/src/sys_common/remutex.rs b/library/std/src/sys_common/remutex.rs index 4f19bbc467f..360337c030b 100644 --- a/library/std/src/sys_common/remutex.rs +++ b/library/std/src/sys_common/remutex.rs @@ -1,3 +1,6 @@ +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::fmt; use crate::marker; use crate::ops::Deref; @@ -146,79 +149,3 @@ impl<T> Drop for ReentrantMutexGuard<'_, T> { } } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::cell::RefCell; - use crate::sync::Arc; - use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; - use crate::thread; - - #[test] - fn smoke() { - let m = unsafe { - let m = ReentrantMutex::new(()); - m.init(); - m - }; - { - let a = m.lock(); - { - let b = m.lock(); - { - let c = m.lock(); - assert_eq!(*c, ()); - } - assert_eq!(*b, ()); - } - assert_eq!(*a, ()); - } - } - - #[test] - fn is_mutex() { - let m = unsafe { - let m = Arc::new(ReentrantMutex::new(RefCell::new(0))); - m.init(); - m - }; - let m2 = m.clone(); - let lock = m.lock(); - let child = thread::spawn(move || { - let lock = m2.lock(); - assert_eq!(*lock.borrow(), 4950); - }); - for i in 0..100 { - let lock = m.lock(); - *lock.borrow_mut() += i; - } - drop(lock); - child.join().unwrap(); - } - - #[test] - fn trylock_works() { - let m = unsafe { - let m = Arc::new(ReentrantMutex::new(())); - m.init(); - m - }; - let m2 = m.clone(); - let _lock = m.try_lock(); - let _lock2 = m.try_lock(); - thread::spawn(move || { - let lock = m2.try_lock(); - assert!(lock.is_none()); - }) - .join() - .unwrap(); - let _lock3 = m.try_lock(); - } - - pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>); - impl Drop for Answer<'_> { - fn drop(&mut self) { - *self.0.borrow_mut() = 42; - } - } -} diff --git a/library/std/src/sys_common/remutex/tests.rs b/library/std/src/sys_common/remutex/tests.rs new file mode 100644 index 00000000000..9c686e579d7 --- /dev/null +++ b/library/std/src/sys_common/remutex/tests.rs @@ -0,0 +1,72 @@ +use crate::cell::RefCell; +use crate::sync::Arc; +use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; +use crate::thread; + +#[test] +fn smoke() { + let m = unsafe { + let m = ReentrantMutex::new(()); + m.init(); + m + }; + { + let a = m.lock(); + { + let b = m.lock(); + { + let c = m.lock(); + assert_eq!(*c, ()); + } + assert_eq!(*b, ()); + } + assert_eq!(*a, ()); + } +} + +#[test] +fn is_mutex() { + let m = unsafe { + let m = Arc::new(ReentrantMutex::new(RefCell::new(0))); + m.init(); + m + }; + let m2 = m.clone(); + let lock = m.lock(); + let child = thread::spawn(move || { + let lock = m2.lock(); + assert_eq!(*lock.borrow(), 4950); + }); + for i in 0..100 { + let lock = m.lock(); + *lock.borrow_mut() += i; + } + drop(lock); + child.join().unwrap(); +} + +#[test] +fn trylock_works() { + let m = unsafe { + let m = Arc::new(ReentrantMutex::new(())); + m.init(); + m + }; + let m2 = m.clone(); + let _lock = m.try_lock(); + let _lock2 = m.try_lock(); + thread::spawn(move || { + let lock = m2.try_lock(); + assert!(lock.is_none()); + }) + .join() + .unwrap(); + let _lock3 = m.try_lock(); +} + +pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>); +impl Drop for Answer<'_> { + fn drop(&mut self) { + *self.0.borrow_mut() = 42; + } +} diff --git a/library/std/src/sys_common/tests.rs b/library/std/src/sys_common/tests.rs new file mode 100644 index 00000000000..1b6446db52d --- /dev/null +++ b/library/std/src/sys_common/tests.rs @@ -0,0 +1,6 @@ +use super::mul_div_u64; + +#[test] +fn test_muldiv() { + assert_eq!(mul_div_u64(1_000_000_000_001, 1_000_000_000, 1_000_000), 1_000_000_000_001_000); +} diff --git a/library/std/src/sys_common/thread_local_key.rs b/library/std/src/sys_common/thread_local_key.rs index ac5b128298d..3a2218854a7 100644 --- a/library/std/src/sys_common/thread_local_key.rs +++ b/library/std/src/sys_common/thread_local_key.rs @@ -48,6 +48,9 @@ #![unstable(feature = "thread_local_internals", issue = "none")] #![allow(dead_code)] // sys isn't exported yet +#[cfg(test)] +mod tests; + use crate::sync::atomic::{self, AtomicUsize, Ordering}; use crate::sys::thread_local_key as imp; use crate::sys_common::mutex::Mutex; @@ -231,41 +234,3 @@ impl Drop for Key { // unsafe { imp::destroy(self.key) } } } - -#[cfg(test)] -mod tests { - use super::{Key, StaticKey}; - - fn assert_sync<T: Sync>() {} - fn assert_send<T: Send>() {} - - #[test] - fn smoke() { - assert_sync::<Key>(); - assert_send::<Key>(); - - let k1 = Key::new(None); - let k2 = Key::new(None); - assert!(k1.get().is_null()); - assert!(k2.get().is_null()); - k1.set(1 as *mut _); - k2.set(2 as *mut _); - assert_eq!(k1.get() as usize, 1); - assert_eq!(k2.get() as usize, 2); - } - - #[test] - fn statik() { - static K1: StaticKey = StaticKey::new(None); - static K2: StaticKey = StaticKey::new(None); - - unsafe { - assert!(K1.get().is_null()); - assert!(K2.get().is_null()); - K1.set(1 as *mut _); - K2.set(2 as *mut _); - assert_eq!(K1.get() as usize, 1); - assert_eq!(K2.get() as usize, 2); - } - } -} diff --git a/library/std/src/sys_common/thread_local_key/tests.rs b/library/std/src/sys_common/thread_local_key/tests.rs new file mode 100644 index 00000000000..968738a4180 --- /dev/null +++ b/library/std/src/sys_common/thread_local_key/tests.rs @@ -0,0 +1,34 @@ +use super::{Key, StaticKey}; + +fn assert_sync<T: Sync>() {} +fn assert_send<T: Send>() {} + +#[test] +fn smoke() { + assert_sync::<Key>(); + assert_send::<Key>(); + + let k1 = Key::new(None); + let k2 = Key::new(None); + assert!(k1.get().is_null()); + assert!(k2.get().is_null()); + k1.set(1 as *mut _); + k2.set(2 as *mut _); + assert_eq!(k1.get() as usize, 1); + assert_eq!(k2.get() as usize, 2); +} + +#[test] +fn statik() { + static K1: StaticKey = StaticKey::new(None); + static K2: StaticKey = StaticKey::new(None); + + unsafe { + assert!(K1.get().is_null()); + assert!(K2.get().is_null()); + K1.set(1 as *mut _); + K2.set(2 as *mut _); + assert_eq!(K1.get() as usize, 1); + assert_eq!(K2.get() as usize, 2); + } +} diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index bdb6a05464e..7d4b0d52831 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -15,6 +15,9 @@ // unix (it's mostly used on windows), so don't worry about dead code here. #![allow(dead_code)] +#[cfg(test)] +mod tests; + use core::str::next_code_point; use crate::borrow::Cow; @@ -879,407 +882,3 @@ impl Hash for Wtf8 { 0xfeu8.hash(state) } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::borrow::Cow; - - #[test] - fn code_point_from_u32() { - assert!(CodePoint::from_u32(0).is_some()); - assert!(CodePoint::from_u32(0xD800).is_some()); - assert!(CodePoint::from_u32(0x10FFFF).is_some()); - assert!(CodePoint::from_u32(0x110000).is_none()); - } - - #[test] - fn code_point_to_u32() { - fn c(value: u32) -> CodePoint { - CodePoint::from_u32(value).unwrap() - } - assert_eq!(c(0).to_u32(), 0); - assert_eq!(c(0xD800).to_u32(), 0xD800); - assert_eq!(c(0x10FFFF).to_u32(), 0x10FFFF); - } - - #[test] - fn code_point_from_char() { - assert_eq!(CodePoint::from_char('a').to_u32(), 0x61); - assert_eq!(CodePoint::from_char('💩').to_u32(), 0x1F4A9); - } - - #[test] - fn code_point_to_string() { - assert_eq!(format!("{:?}", CodePoint::from_char('a')), "U+0061"); - assert_eq!(format!("{:?}", CodePoint::from_char('💩')), "U+1F4A9"); - } - - #[test] - fn code_point_to_char() { - fn c(value: u32) -> CodePoint { - CodePoint::from_u32(value).unwrap() - } - assert_eq!(c(0x61).to_char(), Some('a')); - assert_eq!(c(0x1F4A9).to_char(), Some('💩')); - assert_eq!(c(0xD800).to_char(), None); - } - - #[test] - fn code_point_to_char_lossy() { - fn c(value: u32) -> CodePoint { - CodePoint::from_u32(value).unwrap() - } - assert_eq!(c(0x61).to_char_lossy(), 'a'); - assert_eq!(c(0x1F4A9).to_char_lossy(), '💩'); - assert_eq!(c(0xD800).to_char_lossy(), '\u{FFFD}'); - } - - #[test] - fn wtf8buf_new() { - assert_eq!(Wtf8Buf::new().bytes, b""); - } - - #[test] - fn wtf8buf_from_str() { - assert_eq!(Wtf8Buf::from_str("").bytes, b""); - assert_eq!(Wtf8Buf::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - } - - #[test] - fn wtf8buf_from_string() { - assert_eq!(Wtf8Buf::from_string(String::from("")).bytes, b""); - assert_eq!( - Wtf8Buf::from_string(String::from("aé 💩")).bytes, - b"a\xC3\xA9 \xF0\x9F\x92\xA9" - ); - } - - #[test] - fn wtf8buf_from_wide() { - assert_eq!(Wtf8Buf::from_wide(&[]).bytes, b""); - assert_eq!( - Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]).bytes, - b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9" - ); - } - - #[test] - fn wtf8buf_push_str() { - let mut string = Wtf8Buf::new(); - assert_eq!(string.bytes, b""); - string.push_str("aé 💩"); - assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - } - - #[test] - fn wtf8buf_push_char() { - let mut string = Wtf8Buf::from_str("aé "); - assert_eq!(string.bytes, b"a\xC3\xA9 "); - string.push_char('💩'); - assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - } - - #[test] - fn wtf8buf_push() { - let mut string = Wtf8Buf::from_str("aé "); - assert_eq!(string.bytes, b"a\xC3\xA9 "); - string.push(CodePoint::from_char('💩')); - assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - - fn c(value: u32) -> CodePoint { - CodePoint::from_u32(value).unwrap() - } - - let mut string = Wtf8Buf::new(); - string.push(c(0xD83D)); // lead - string.push(c(0xDCA9)); // trail - assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic! - - let mut string = Wtf8Buf::new(); - string.push(c(0xD83D)); // lead - string.push(c(0x20)); // not surrogate - string.push(c(0xDCA9)); // trail - assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); - - let mut string = Wtf8Buf::new(); - string.push(c(0xD800)); // lead - string.push(c(0xDBFF)); // lead - assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF"); - - let mut string = Wtf8Buf::new(); - string.push(c(0xD800)); // lead - string.push(c(0xE000)); // not surrogate - assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80"); - - let mut string = Wtf8Buf::new(); - string.push(c(0xD7FF)); // not surrogate - string.push(c(0xDC00)); // trail - assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80"); - - let mut string = Wtf8Buf::new(); - string.push(c(0x61)); // not surrogate, < 3 bytes - string.push(c(0xDC00)); // trail - assert_eq!(string.bytes, b"\x61\xED\xB0\x80"); - - let mut string = Wtf8Buf::new(); - string.push(c(0xDC00)); // trail - assert_eq!(string.bytes, b"\xED\xB0\x80"); - } - - #[test] - fn wtf8buf_push_wtf8() { - let mut string = Wtf8Buf::from_str("aé"); - assert_eq!(string.bytes, b"a\xC3\xA9"); - string.push_wtf8(Wtf8::from_str(" 💩")); - assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - - fn w(v: &[u8]) -> &Wtf8 { - unsafe { Wtf8::from_bytes_unchecked(v) } - } - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"\xED\xA0\xBD")); // lead - string.push_wtf8(w(b"\xED\xB2\xA9")); // trail - assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic! - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"\xED\xA0\xBD")); // lead - string.push_wtf8(w(b" ")); // not surrogate - string.push_wtf8(w(b"\xED\xB2\xA9")); // trail - assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"\xED\xA0\x80")); // lead - string.push_wtf8(w(b"\xED\xAF\xBF")); // lead - assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF"); - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"\xED\xA0\x80")); // lead - string.push_wtf8(w(b"\xEE\x80\x80")); // not surrogate - assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80"); - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"\xED\x9F\xBF")); // not surrogate - string.push_wtf8(w(b"\xED\xB0\x80")); // trail - assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80"); - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"a")); // not surrogate, < 3 bytes - string.push_wtf8(w(b"\xED\xB0\x80")); // trail - assert_eq!(string.bytes, b"\x61\xED\xB0\x80"); - - let mut string = Wtf8Buf::new(); - string.push_wtf8(w(b"\xED\xB0\x80")); // trail - assert_eq!(string.bytes, b"\xED\xB0\x80"); - } - - #[test] - fn wtf8buf_truncate() { - let mut string = Wtf8Buf::from_str("aé"); - string.truncate(1); - assert_eq!(string.bytes, b"a"); - } - - #[test] - #[should_panic] - fn wtf8buf_truncate_fail_code_point_boundary() { - let mut string = Wtf8Buf::from_str("aé"); - string.truncate(2); - } - - #[test] - #[should_panic] - fn wtf8buf_truncate_fail_longer() { - let mut string = Wtf8Buf::from_str("aé"); - string.truncate(4); - } - - #[test] - fn wtf8buf_into_string() { - let mut string = Wtf8Buf::from_str("aé 💩"); - assert_eq!(string.clone().into_string(), Ok(String::from("aé 💩"))); - string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(string.clone().into_string(), Err(string)); - } - - #[test] - fn wtf8buf_into_string_lossy() { - let mut string = Wtf8Buf::from_str("aé 💩"); - assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩")); - string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩�")); - } - - #[test] - fn wtf8buf_from_iterator() { - fn f(values: &[u32]) -> Wtf8Buf { - values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>() - } - assert_eq!(f(&[0x61, 0xE9, 0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - - assert_eq!(f(&[0xD83D, 0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic! - assert_eq!(f(&[0xD83D, 0x20, 0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); - assert_eq!(f(&[0xD800, 0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF"); - assert_eq!(f(&[0xD800, 0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80"); - assert_eq!(f(&[0xD7FF, 0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80"); - assert_eq!(f(&[0x61, 0xDC00]).bytes, b"\x61\xED\xB0\x80"); - assert_eq!(f(&[0xDC00]).bytes, b"\xED\xB0\x80"); - } - - #[test] - fn wtf8buf_extend() { - fn e(initial: &[u32], extended: &[u32]) -> Wtf8Buf { - fn c(value: &u32) -> CodePoint { - CodePoint::from_u32(*value).unwrap() - } - let mut string = initial.iter().map(c).collect::<Wtf8Buf>(); - string.extend(extended.iter().map(c)); - string - } - - assert_eq!(e(&[0x61, 0xE9], &[0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - - assert_eq!(e(&[0xD83D], &[0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic! - assert_eq!(e(&[0xD83D, 0x20], &[0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); - assert_eq!(e(&[0xD800], &[0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF"); - assert_eq!(e(&[0xD800], &[0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80"); - assert_eq!(e(&[0xD7FF], &[0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80"); - assert_eq!(e(&[0x61], &[0xDC00]).bytes, b"\x61\xED\xB0\x80"); - assert_eq!(e(&[], &[0xDC00]).bytes, b"\xED\xB0\x80"); - } - - #[test] - fn wtf8buf_show() { - let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r"); - string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\""); - } - - #[test] - fn wtf8buf_as_slice() { - assert_eq!(Wtf8Buf::from_str("aé").as_slice(), Wtf8::from_str("aé")); - } - - #[test] - fn wtf8buf_show_str() { - let text = "a\té 💩\r"; - let string = Wtf8Buf::from_str(text); - assert_eq!(format!("{:?}", text), format!("{:?}", string)); - } - - #[test] - fn wtf8_from_str() { - assert_eq!(&Wtf8::from_str("").bytes, b""); - assert_eq!(&Wtf8::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); - } - - #[test] - fn wtf8_len() { - assert_eq!(Wtf8::from_str("").len(), 0); - assert_eq!(Wtf8::from_str("aé 💩").len(), 8); - } - - #[test] - fn wtf8_slice() { - assert_eq!(&Wtf8::from_str("aé 💩")[1..4].bytes, b"\xC3\xA9 "); - } - - #[test] - #[should_panic] - fn wtf8_slice_not_code_point_boundary() { - &Wtf8::from_str("aé 💩")[2..4]; - } - - #[test] - fn wtf8_slice_from() { - assert_eq!(&Wtf8::from_str("aé 💩")[1..].bytes, b"\xC3\xA9 \xF0\x9F\x92\xA9"); - } - - #[test] - #[should_panic] - fn wtf8_slice_from_not_code_point_boundary() { - &Wtf8::from_str("aé 💩")[2..]; - } - - #[test] - fn wtf8_slice_to() { - assert_eq!(&Wtf8::from_str("aé 💩")[..4].bytes, b"a\xC3\xA9 "); - } - - #[test] - #[should_panic] - fn wtf8_slice_to_not_code_point_boundary() { - &Wtf8::from_str("aé 💩")[5..]; - } - - #[test] - fn wtf8_ascii_byte_at() { - let slice = Wtf8::from_str("aé 💩"); - assert_eq!(slice.ascii_byte_at(0), b'a'); - assert_eq!(slice.ascii_byte_at(1), b'\xFF'); - assert_eq!(slice.ascii_byte_at(2), b'\xFF'); - assert_eq!(slice.ascii_byte_at(3), b' '); - assert_eq!(slice.ascii_byte_at(4), b'\xFF'); - } - - #[test] - fn wtf8_code_points() { - fn c(value: u32) -> CodePoint { - CodePoint::from_u32(value).unwrap() - } - fn cp(string: &Wtf8Buf) -> Vec<Option<char>> { - string.code_points().map(|c| c.to_char()).collect::<Vec<_>>() - } - let mut string = Wtf8Buf::from_str("é "); - assert_eq!(cp(&string), [Some('é'), Some(' ')]); - string.push(c(0xD83D)); - assert_eq!(cp(&string), [Some('é'), Some(' '), None]); - string.push(c(0xDCA9)); - assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]); - } - - #[test] - fn wtf8_as_str() { - assert_eq!(Wtf8::from_str("").as_str(), Some("")); - assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩")); - let mut string = Wtf8Buf::new(); - string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!(string.as_str(), None); - } - - #[test] - fn wtf8_to_string_lossy() { - assert_eq!(Wtf8::from_str("").to_string_lossy(), Cow::Borrowed("")); - assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩")); - let mut string = Wtf8Buf::from_str("aé 💩"); - string.push(CodePoint::from_u32(0xD800).unwrap()); - let expected: Cow<'_, str> = Cow::Owned(String::from("aé 💩�")); - assert_eq!(string.to_string_lossy(), expected); - } - - #[test] - fn wtf8_display() { - fn d(b: &[u8]) -> String { - (&unsafe { Wtf8::from_bytes_unchecked(b) }).to_string() - } - - assert_eq!("", d("".as_bytes())); - assert_eq!("aé 💩", d("aé 💩".as_bytes())); - - let mut string = Wtf8Buf::from_str("aé 💩"); - string.push(CodePoint::from_u32(0xD800).unwrap()); - assert_eq!("aé 💩�", d(string.as_inner())); - } - - #[test] - fn wtf8_encode_wide() { - let mut string = Wtf8Buf::from_str("aé "); - string.push(CodePoint::from_u32(0xD83D).unwrap()); - string.push_char('💩'); - assert_eq!( - string.encode_wide().collect::<Vec<_>>(), - vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9] - ); - } -} diff --git a/library/std/src/sys_common/wtf8/tests.rs b/library/std/src/sys_common/wtf8/tests.rs new file mode 100644 index 00000000000..385e01f92fa --- /dev/null +++ b/library/std/src/sys_common/wtf8/tests.rs @@ -0,0 +1,397 @@ +use super::*; +use crate::borrow::Cow; + +#[test] +fn code_point_from_u32() { + assert!(CodePoint::from_u32(0).is_some()); + assert!(CodePoint::from_u32(0xD800).is_some()); + assert!(CodePoint::from_u32(0x10FFFF).is_some()); + assert!(CodePoint::from_u32(0x110000).is_none()); +} + +#[test] +fn code_point_to_u32() { + fn c(value: u32) -> CodePoint { + CodePoint::from_u32(value).unwrap() + } + assert_eq!(c(0).to_u32(), 0); + assert_eq!(c(0xD800).to_u32(), 0xD800); + assert_eq!(c(0x10FFFF).to_u32(), 0x10FFFF); +} + +#[test] +fn code_point_from_char() { + assert_eq!(CodePoint::from_char('a').to_u32(), 0x61); + assert_eq!(CodePoint::from_char('💩').to_u32(), 0x1F4A9); +} + +#[test] +fn code_point_to_string() { + assert_eq!(format!("{:?}", CodePoint::from_char('a')), "U+0061"); + assert_eq!(format!("{:?}", CodePoint::from_char('💩')), "U+1F4A9"); +} + +#[test] +fn code_point_to_char() { + fn c(value: u32) -> CodePoint { + CodePoint::from_u32(value).unwrap() + } + assert_eq!(c(0x61).to_char(), Some('a')); + assert_eq!(c(0x1F4A9).to_char(), Some('💩')); + assert_eq!(c(0xD800).to_char(), None); +} + +#[test] +fn code_point_to_char_lossy() { + fn c(value: u32) -> CodePoint { + CodePoint::from_u32(value).unwrap() + } + assert_eq!(c(0x61).to_char_lossy(), 'a'); + assert_eq!(c(0x1F4A9).to_char_lossy(), '💩'); + assert_eq!(c(0xD800).to_char_lossy(), '\u{FFFD}'); +} + +#[test] +fn wtf8buf_new() { + assert_eq!(Wtf8Buf::new().bytes, b""); +} + +#[test] +fn wtf8buf_from_str() { + assert_eq!(Wtf8Buf::from_str("").bytes, b""); + assert_eq!(Wtf8Buf::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); +} + +#[test] +fn wtf8buf_from_string() { + assert_eq!(Wtf8Buf::from_string(String::from("")).bytes, b""); + assert_eq!(Wtf8Buf::from_string(String::from("aé 💩")).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); +} + +#[test] +fn wtf8buf_from_wide() { + assert_eq!(Wtf8Buf::from_wide(&[]).bytes, b""); + assert_eq!( + Wtf8Buf::from_wide(&[0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]).bytes, + b"a\xC3\xA9 \xED\xA0\xBD\xF0\x9F\x92\xA9" + ); +} + +#[test] +fn wtf8buf_push_str() { + let mut string = Wtf8Buf::new(); + assert_eq!(string.bytes, b""); + string.push_str("aé 💩"); + assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); +} + +#[test] +fn wtf8buf_push_char() { + let mut string = Wtf8Buf::from_str("aé "); + assert_eq!(string.bytes, b"a\xC3\xA9 "); + string.push_char('💩'); + assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); +} + +#[test] +fn wtf8buf_push() { + let mut string = Wtf8Buf::from_str("aé "); + assert_eq!(string.bytes, b"a\xC3\xA9 "); + string.push(CodePoint::from_char('💩')); + assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); + + fn c(value: u32) -> CodePoint { + CodePoint::from_u32(value).unwrap() + } + + let mut string = Wtf8Buf::new(); + string.push(c(0xD83D)); // lead + string.push(c(0xDCA9)); // trail + assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic! + + let mut string = Wtf8Buf::new(); + string.push(c(0xD83D)); // lead + string.push(c(0x20)); // not surrogate + string.push(c(0xDCA9)); // trail + assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); + + let mut string = Wtf8Buf::new(); + string.push(c(0xD800)); // lead + string.push(c(0xDBFF)); // lead + assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF"); + + let mut string = Wtf8Buf::new(); + string.push(c(0xD800)); // lead + string.push(c(0xE000)); // not surrogate + assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80"); + + let mut string = Wtf8Buf::new(); + string.push(c(0xD7FF)); // not surrogate + string.push(c(0xDC00)); // trail + assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80"); + + let mut string = Wtf8Buf::new(); + string.push(c(0x61)); // not surrogate, < 3 bytes + string.push(c(0xDC00)); // trail + assert_eq!(string.bytes, b"\x61\xED\xB0\x80"); + + let mut string = Wtf8Buf::new(); + string.push(c(0xDC00)); // trail + assert_eq!(string.bytes, b"\xED\xB0\x80"); +} + +#[test] +fn wtf8buf_push_wtf8() { + let mut string = Wtf8Buf::from_str("aé"); + assert_eq!(string.bytes, b"a\xC3\xA9"); + string.push_wtf8(Wtf8::from_str(" 💩")); + assert_eq!(string.bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); + + fn w(v: &[u8]) -> &Wtf8 { + unsafe { Wtf8::from_bytes_unchecked(v) } + } + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"\xED\xA0\xBD")); // lead + string.push_wtf8(w(b"\xED\xB2\xA9")); // trail + assert_eq!(string.bytes, b"\xF0\x9F\x92\xA9"); // Magic! + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"\xED\xA0\xBD")); // lead + string.push_wtf8(w(b" ")); // not surrogate + string.push_wtf8(w(b"\xED\xB2\xA9")); // trail + assert_eq!(string.bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"\xED\xA0\x80")); // lead + string.push_wtf8(w(b"\xED\xAF\xBF")); // lead + assert_eq!(string.bytes, b"\xED\xA0\x80\xED\xAF\xBF"); + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"\xED\xA0\x80")); // lead + string.push_wtf8(w(b"\xEE\x80\x80")); // not surrogate + assert_eq!(string.bytes, b"\xED\xA0\x80\xEE\x80\x80"); + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"\xED\x9F\xBF")); // not surrogate + string.push_wtf8(w(b"\xED\xB0\x80")); // trail + assert_eq!(string.bytes, b"\xED\x9F\xBF\xED\xB0\x80"); + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"a")); // not surrogate, < 3 bytes + string.push_wtf8(w(b"\xED\xB0\x80")); // trail + assert_eq!(string.bytes, b"\x61\xED\xB0\x80"); + + let mut string = Wtf8Buf::new(); + string.push_wtf8(w(b"\xED\xB0\x80")); // trail + assert_eq!(string.bytes, b"\xED\xB0\x80"); +} + +#[test] +fn wtf8buf_truncate() { + let mut string = Wtf8Buf::from_str("aé"); + string.truncate(1); + assert_eq!(string.bytes, b"a"); +} + +#[test] +#[should_panic] +fn wtf8buf_truncate_fail_code_point_boundary() { + let mut string = Wtf8Buf::from_str("aé"); + string.truncate(2); +} + +#[test] +#[should_panic] +fn wtf8buf_truncate_fail_longer() { + let mut string = Wtf8Buf::from_str("aé"); + string.truncate(4); +} + +#[test] +fn wtf8buf_into_string() { + let mut string = Wtf8Buf::from_str("aé 💩"); + assert_eq!(string.clone().into_string(), Ok(String::from("aé 💩"))); + string.push(CodePoint::from_u32(0xD800).unwrap()); + assert_eq!(string.clone().into_string(), Err(string)); +} + +#[test] +fn wtf8buf_into_string_lossy() { + let mut string = Wtf8Buf::from_str("aé 💩"); + assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩")); + string.push(CodePoint::from_u32(0xD800).unwrap()); + assert_eq!(string.clone().into_string_lossy(), String::from("aé 💩�")); +} + +#[test] +fn wtf8buf_from_iterator() { + fn f(values: &[u32]) -> Wtf8Buf { + values.iter().map(|&c| CodePoint::from_u32(c).unwrap()).collect::<Wtf8Buf>() + } + assert_eq!(f(&[0x61, 0xE9, 0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); + + assert_eq!(f(&[0xD83D, 0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic! + assert_eq!(f(&[0xD83D, 0x20, 0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); + assert_eq!(f(&[0xD800, 0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF"); + assert_eq!(f(&[0xD800, 0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80"); + assert_eq!(f(&[0xD7FF, 0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80"); + assert_eq!(f(&[0x61, 0xDC00]).bytes, b"\x61\xED\xB0\x80"); + assert_eq!(f(&[0xDC00]).bytes, b"\xED\xB0\x80"); +} + +#[test] +fn wtf8buf_extend() { + fn e(initial: &[u32], extended: &[u32]) -> Wtf8Buf { + fn c(value: &u32) -> CodePoint { + CodePoint::from_u32(*value).unwrap() + } + let mut string = initial.iter().map(c).collect::<Wtf8Buf>(); + string.extend(extended.iter().map(c)); + string + } + + assert_eq!(e(&[0x61, 0xE9], &[0x20, 0x1F4A9]).bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); + + assert_eq!(e(&[0xD83D], &[0xDCA9]).bytes, b"\xF0\x9F\x92\xA9"); // Magic! + assert_eq!(e(&[0xD83D, 0x20], &[0xDCA9]).bytes, b"\xED\xA0\xBD \xED\xB2\xA9"); + assert_eq!(e(&[0xD800], &[0xDBFF]).bytes, b"\xED\xA0\x80\xED\xAF\xBF"); + assert_eq!(e(&[0xD800], &[0xE000]).bytes, b"\xED\xA0\x80\xEE\x80\x80"); + assert_eq!(e(&[0xD7FF], &[0xDC00]).bytes, b"\xED\x9F\xBF\xED\xB0\x80"); + assert_eq!(e(&[0x61], &[0xDC00]).bytes, b"\x61\xED\xB0\x80"); + assert_eq!(e(&[], &[0xDC00]).bytes, b"\xED\xB0\x80"); +} + +#[test] +fn wtf8buf_show() { + let mut string = Wtf8Buf::from_str("a\té \u{7f}💩\r"); + string.push(CodePoint::from_u32(0xD800).unwrap()); + assert_eq!(format!("{:?}", string), "\"a\\té \\u{7f}\u{1f4a9}\\r\\u{d800}\""); +} + +#[test] +fn wtf8buf_as_slice() { + assert_eq!(Wtf8Buf::from_str("aé").as_slice(), Wtf8::from_str("aé")); +} + +#[test] +fn wtf8buf_show_str() { + let text = "a\té 💩\r"; + let string = Wtf8Buf::from_str(text); + assert_eq!(format!("{:?}", text), format!("{:?}", string)); +} + +#[test] +fn wtf8_from_str() { + assert_eq!(&Wtf8::from_str("").bytes, b""); + assert_eq!(&Wtf8::from_str("aé 💩").bytes, b"a\xC3\xA9 \xF0\x9F\x92\xA9"); +} + +#[test] +fn wtf8_len() { + assert_eq!(Wtf8::from_str("").len(), 0); + assert_eq!(Wtf8::from_str("aé 💩").len(), 8); +} + +#[test] +fn wtf8_slice() { + assert_eq!(&Wtf8::from_str("aé 💩")[1..4].bytes, b"\xC3\xA9 "); +} + +#[test] +#[should_panic] +fn wtf8_slice_not_code_point_boundary() { + &Wtf8::from_str("aé 💩")[2..4]; +} + +#[test] +fn wtf8_slice_from() { + assert_eq!(&Wtf8::from_str("aé 💩")[1..].bytes, b"\xC3\xA9 \xF0\x9F\x92\xA9"); +} + +#[test] +#[should_panic] +fn wtf8_slice_from_not_code_point_boundary() { + &Wtf8::from_str("aé 💩")[2..]; +} + +#[test] +fn wtf8_slice_to() { + assert_eq!(&Wtf8::from_str("aé 💩")[..4].bytes, b"a\xC3\xA9 "); +} + +#[test] +#[should_panic] +fn wtf8_slice_to_not_code_point_boundary() { + &Wtf8::from_str("aé 💩")[5..]; +} + +#[test] +fn wtf8_ascii_byte_at() { + let slice = Wtf8::from_str("aé 💩"); + assert_eq!(slice.ascii_byte_at(0), b'a'); + assert_eq!(slice.ascii_byte_at(1), b'\xFF'); + assert_eq!(slice.ascii_byte_at(2), b'\xFF'); + assert_eq!(slice.ascii_byte_at(3), b' '); + assert_eq!(slice.ascii_byte_at(4), b'\xFF'); +} + +#[test] +fn wtf8_code_points() { + fn c(value: u32) -> CodePoint { + CodePoint::from_u32(value).unwrap() + } + fn cp(string: &Wtf8Buf) -> Vec<Option<char>> { + string.code_points().map(|c| c.to_char()).collect::<Vec<_>>() + } + let mut string = Wtf8Buf::from_str("é "); + assert_eq!(cp(&string), [Some('é'), Some(' ')]); + string.push(c(0xD83D)); + assert_eq!(cp(&string), [Some('é'), Some(' '), None]); + string.push(c(0xDCA9)); + assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]); +} + +#[test] +fn wtf8_as_str() { + assert_eq!(Wtf8::from_str("").as_str(), Some("")); + assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩")); + let mut string = Wtf8Buf::new(); + string.push(CodePoint::from_u32(0xD800).unwrap()); + assert_eq!(string.as_str(), None); +} + +#[test] +fn wtf8_to_string_lossy() { + assert_eq!(Wtf8::from_str("").to_string_lossy(), Cow::Borrowed("")); + assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩")); + let mut string = Wtf8Buf::from_str("aé 💩"); + string.push(CodePoint::from_u32(0xD800).unwrap()); + let expected: Cow<'_, str> = Cow::Owned(String::from("aé 💩�")); + assert_eq!(string.to_string_lossy(), expected); +} + +#[test] +fn wtf8_display() { + fn d(b: &[u8]) -> String { + (&unsafe { Wtf8::from_bytes_unchecked(b) }).to_string() + } + + assert_eq!("", d("".as_bytes())); + assert_eq!("aé 💩", d("aé 💩".as_bytes())); + + let mut string = Wtf8Buf::from_str("aé 💩"); + string.push(CodePoint::from_u32(0xD800).unwrap()); + assert_eq!("aé 💩�", d(string.as_inner())); +} + +#[test] +fn wtf8_encode_wide() { + let mut string = Wtf8Buf::from_str("aé "); + string.push(CodePoint::from_u32(0xD83D).unwrap()); + string.push_char('💩'); + assert_eq!( + string.encode_wide().collect::<Vec<_>>(), + vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9] + ); +} diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index a4562967f0b..9d8c6f1815e 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -2,6 +2,12 @@ #![unstable(feature = "thread_local_internals", issue = "none")] +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + +#[cfg(test)] +mod dynamic_tests; + use crate::error::Error; use crate::fmt; @@ -547,203 +553,3 @@ pub mod os { key.os.set(ptr::null_mut()); } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::cell::{Cell, UnsafeCell}; - use crate::sync::mpsc::{channel, Sender}; - use crate::thread; - - struct Foo(Sender<()>); - - impl Drop for Foo { - fn drop(&mut self) { - let Foo(ref s) = *self; - s.send(()).unwrap(); - } - } - - #[test] - fn smoke_no_dtor() { - thread_local!(static FOO: Cell<i32> = Cell::new(1)); - - FOO.with(|f| { - assert_eq!(f.get(), 1); - f.set(2); - }); - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - FOO.with(|f| { - assert_eq!(f.get(), 1); - }); - tx.send(()).unwrap(); - }); - rx.recv().unwrap(); - - FOO.with(|f| { - assert_eq!(f.get(), 2); - }); - } - - #[test] - fn states() { - struct Foo; - impl Drop for Foo { - fn drop(&mut self) { - assert!(FOO.try_with(|_| ()).is_err()); - } - } - thread_local!(static FOO: Foo = Foo); - - thread::spawn(|| { - assert!(FOO.try_with(|_| ()).is_ok()); - }) - .join() - .ok() - .expect("thread panicked"); - } - - #[test] - fn smoke_dtor() { - thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell::new(None)); - - let (tx, rx) = channel(); - let _t = thread::spawn(move || unsafe { - let mut tx = Some(tx); - FOO.with(|f| { - *f.get() = Some(Foo(tx.take().unwrap())); - }); - }); - rx.recv().unwrap(); - } - - #[test] - fn circular() { - struct S1; - struct S2; - thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); - thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell::new(None)); - static mut HITS: u32 = 0; - - impl Drop for S1 { - fn drop(&mut self) { - unsafe { - HITS += 1; - if K2.try_with(|_| ()).is_err() { - assert_eq!(HITS, 3); - } else { - if HITS == 1 { - K2.with(|s| *s.get() = Some(S2)); - } else { - assert_eq!(HITS, 3); - } - } - } - } - } - impl Drop for S2 { - fn drop(&mut self) { - unsafe { - HITS += 1; - assert!(K1.try_with(|_| ()).is_ok()); - assert_eq!(HITS, 2); - K1.with(|s| *s.get() = Some(S1)); - } - } - } - - thread::spawn(move || { - drop(S1); - }) - .join() - .ok() - .expect("thread panicked"); - } - - #[test] - fn self_referential() { - struct S1; - thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); - - impl Drop for S1 { - fn drop(&mut self) { - assert!(K1.try_with(|_| ()).is_err()); - } - } - - thread::spawn(move || unsafe { - K1.with(|s| *s.get() = Some(S1)); - }) - .join() - .ok() - .expect("thread panicked"); - } - - // Note that this test will deadlock if TLS destructors aren't run (this - // requires the destructor to be run to pass the test). - #[test] - fn dtors_in_dtors_in_dtors() { - struct S1(Sender<()>); - thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); - thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None)); - - impl Drop for S1 { - fn drop(&mut self) { - let S1(ref tx) = *self; - unsafe { - let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone()))); - } - } - } - - let (tx, rx) = channel(); - let _t = thread::spawn(move || unsafe { - let mut tx = Some(tx); - K1.with(|s| *s.get() = Some(S1(tx.take().unwrap()))); - }); - rx.recv().unwrap(); - } -} - -#[cfg(test)] -mod dynamic_tests { - use crate::cell::RefCell; - use crate::collections::HashMap; - - #[test] - fn smoke() { - fn square(i: i32) -> i32 { - i * i - } - thread_local!(static FOO: i32 = square(3)); - - FOO.with(|f| { - assert_eq!(*f, 9); - }); - } - - #[test] - fn hashmap() { - fn map() -> RefCell<HashMap<i32, i32>> { - let mut m = HashMap::new(); - m.insert(1, 2); - RefCell::new(m) - } - thread_local!(static FOO: RefCell<HashMap<i32, i32>> = map()); - - FOO.with(|map| { - assert_eq!(map.borrow()[&1], 2); - }); - } - - #[test] - fn refcell_vec() { - thread_local!(static FOO: RefCell<Vec<u32>> = RefCell::new(vec![1, 2, 3])); - - FOO.with(|vec| { - assert_eq!(vec.borrow().len(), 3); - vec.borrow_mut().push(4); - assert_eq!(vec.borrow()[3], 4); - }); - } -} diff --git a/library/std/src/thread/local/dynamic_tests.rs b/library/std/src/thread/local/dynamic_tests.rs new file mode 100644 index 00000000000..dd180041648 --- /dev/null +++ b/library/std/src/thread/local/dynamic_tests.rs @@ -0,0 +1,40 @@ +use crate::cell::RefCell; +use crate::collections::HashMap; +use crate::thread_local; + +#[test] +fn smoke() { + fn square(i: i32) -> i32 { + i * i + } + thread_local!(static FOO: i32 = square(3)); + + FOO.with(|f| { + assert_eq!(*f, 9); + }); +} + +#[test] +fn hashmap() { + fn map() -> RefCell<HashMap<i32, i32>> { + let mut m = HashMap::new(); + m.insert(1, 2); + RefCell::new(m) + } + thread_local!(static FOO: RefCell<HashMap<i32, i32>> = map()); + + FOO.with(|map| { + assert_eq!(map.borrow()[&1], 2); + }); +} + +#[test] +fn refcell_vec() { + thread_local!(static FOO: RefCell<Vec<u32>> = RefCell::new(vec![1, 2, 3])); + + FOO.with(|vec| { + assert_eq!(vec.borrow().len(), 3); + vec.borrow_mut().push(4); + assert_eq!(vec.borrow()[3], 4); + }); +} diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs new file mode 100644 index 00000000000..4fb0a089082 --- /dev/null +++ b/library/std/src/thread/local/tests.rs @@ -0,0 +1,154 @@ +use crate::cell::{Cell, UnsafeCell}; +use crate::sync::mpsc::{channel, Sender}; +use crate::thread; +use crate::thread_local; + +struct Foo(Sender<()>); + +impl Drop for Foo { + fn drop(&mut self) { + let Foo(ref s) = *self; + s.send(()).unwrap(); + } +} + +#[test] +fn smoke_no_dtor() { + thread_local!(static FOO: Cell<i32> = Cell::new(1)); + + FOO.with(|f| { + assert_eq!(f.get(), 1); + f.set(2); + }); + let (tx, rx) = channel(); + let _t = thread::spawn(move || { + FOO.with(|f| { + assert_eq!(f.get(), 1); + }); + tx.send(()).unwrap(); + }); + rx.recv().unwrap(); + + FOO.with(|f| { + assert_eq!(f.get(), 2); + }); +} + +#[test] +fn states() { + struct Foo; + impl Drop for Foo { + fn drop(&mut self) { + assert!(FOO.try_with(|_| ()).is_err()); + } + } + thread_local!(static FOO: Foo = Foo); + + thread::spawn(|| { + assert!(FOO.try_with(|_| ()).is_ok()); + }) + .join() + .ok() + .expect("thread panicked"); +} + +#[test] +fn smoke_dtor() { + thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell::new(None)); + + let (tx, rx) = channel(); + let _t = thread::spawn(move || unsafe { + let mut tx = Some(tx); + FOO.with(|f| { + *f.get() = Some(Foo(tx.take().unwrap())); + }); + }); + rx.recv().unwrap(); +} + +#[test] +fn circular() { + struct S1; + struct S2; + thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); + thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell::new(None)); + static mut HITS: u32 = 0; + + impl Drop for S1 { + fn drop(&mut self) { + unsafe { + HITS += 1; + if K2.try_with(|_| ()).is_err() { + assert_eq!(HITS, 3); + } else { + if HITS == 1 { + K2.with(|s| *s.get() = Some(S2)); + } else { + assert_eq!(HITS, 3); + } + } + } + } + } + impl Drop for S2 { + fn drop(&mut self) { + unsafe { + HITS += 1; + assert!(K1.try_with(|_| ()).is_ok()); + assert_eq!(HITS, 2); + K1.with(|s| *s.get() = Some(S1)); + } + } + } + + thread::spawn(move || { + drop(S1); + }) + .join() + .ok() + .expect("thread panicked"); +} + +#[test] +fn self_referential() { + struct S1; + thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); + + impl Drop for S1 { + fn drop(&mut self) { + assert!(K1.try_with(|_| ()).is_err()); + } + } + + thread::spawn(move || unsafe { + K1.with(|s| *s.get() = Some(S1)); + }) + .join() + .ok() + .expect("thread panicked"); +} + +// Note that this test will deadlock if TLS destructors aren't run (this +// requires the destructor to be run to pass the test). +#[test] +fn dtors_in_dtors_in_dtors() { + struct S1(Sender<()>); + thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None)); + thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None)); + + impl Drop for S1 { + fn drop(&mut self) { + let S1(ref tx) = *self; + unsafe { + let _ = K2.try_with(|s| *s.get() = Some(Foo(tx.clone()))); + } + } + } + + let (tx, rx) = channel(); + let _t = thread::spawn(move || unsafe { + let mut tx = Some(tx); + K1.with(|s| *s.get() = Some(S1(tx.take().unwrap()))); + }); + rx.recv().unwrap(); +} diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 0b9849517c2..6d6be8560aa 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -145,6 +145,9 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests; + use crate::any::Any; use crate::cell::UnsafeCell; use crate::ffi::{CStr, CString}; @@ -1470,273 +1473,3 @@ fn _assert_sync_and_send() { _assert_both::<JoinHandle<()>>(); _assert_both::<Thread>(); } - -//////////////////////////////////////////////////////////////////////////////// -// Tests -//////////////////////////////////////////////////////////////////////////////// - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use super::Builder; - use crate::any::Any; - use crate::mem; - use crate::result; - use crate::sync::mpsc::{channel, Sender}; - use crate::thread::{self, ThreadId}; - use crate::time::Duration; - - // !!! These tests are dangerous. If something is buggy, they will hang, !!! - // !!! instead of exiting cleanly. This might wedge the buildbots. !!! - - #[test] - fn test_unnamed_thread() { - thread::spawn(move || { - assert!(thread::current().name().is_none()); - }) - .join() - .ok() - .expect("thread panicked"); - } - - #[test] - fn test_named_thread() { - Builder::new() - .name("ada lovelace".to_string()) - .spawn(move || { - assert!(thread::current().name().unwrap() == "ada lovelace".to_string()); - }) - .unwrap() - .join() - .unwrap(); - } - - #[test] - #[should_panic] - fn test_invalid_named_thread() { - let _ = Builder::new().name("ada l\0velace".to_string()).spawn(|| {}); - } - - #[test] - fn test_run_basic() { - let (tx, rx) = channel(); - thread::spawn(move || { - tx.send(()).unwrap(); - }); - rx.recv().unwrap(); - } - - #[test] - fn test_join_panic() { - match thread::spawn(move || panic!()).join() { - result::Result::Err(_) => (), - result::Result::Ok(()) => panic!(), - } - } - - #[test] - fn test_spawn_sched() { - let (tx, rx) = channel(); - - fn f(i: i32, tx: Sender<()>) { - let tx = tx.clone(); - thread::spawn(move || { - if i == 0 { - tx.send(()).unwrap(); - } else { - f(i - 1, tx); - } - }); - } - f(10, tx); - rx.recv().unwrap(); - } - - #[test] - fn test_spawn_sched_childs_on_default_sched() { - let (tx, rx) = channel(); - - thread::spawn(move || { - thread::spawn(move || { - tx.send(()).unwrap(); - }); - }); - - rx.recv().unwrap(); - } - - fn avoid_copying_the_body<F>(spawnfn: F) - where - F: FnOnce(Box<dyn Fn() + Send>), - { - let (tx, rx) = channel(); - - let x: Box<_> = box 1; - let x_in_parent = (&*x) as *const i32 as usize; - - spawnfn(Box::new(move || { - let x_in_child = (&*x) as *const i32 as usize; - tx.send(x_in_child).unwrap(); - })); - - let x_in_child = rx.recv().unwrap(); - assert_eq!(x_in_parent, x_in_child); - } - - #[test] - fn test_avoid_copying_the_body_spawn() { - avoid_copying_the_body(|v| { - thread::spawn(move || v()); - }); - } - - #[test] - fn test_avoid_copying_the_body_thread_spawn() { - avoid_copying_the_body(|f| { - thread::spawn(move || { - f(); - }); - }) - } - - #[test] - fn test_avoid_copying_the_body_join() { - avoid_copying_the_body(|f| { - let _ = thread::spawn(move || f()).join(); - }) - } - - #[test] - fn test_child_doesnt_ref_parent() { - // If the child refcounts the parent thread, this will stack overflow when - // climbing the thread tree to dereference each ancestor. (See #1789) - // (well, it would if the constant were 8000+ - I lowered it to be more - // valgrind-friendly. try this at home, instead..!) - const GENERATIONS: u32 = 16; - fn child_no(x: u32) -> Box<dyn Fn() + Send> { - return Box::new(move || { - if x < GENERATIONS { - thread::spawn(move || child_no(x + 1)()); - } - }); - } - thread::spawn(|| child_no(0)()); - } - - #[test] - fn test_simple_newsched_spawn() { - thread::spawn(move || {}); - } - - #[test] - fn test_try_panic_message_static_str() { - match thread::spawn(move || { - panic!("static string"); - }) - .join() - { - Err(e) => { - type T = &'static str; - assert!(e.is::<T>()); - assert_eq!(*e.downcast::<T>().unwrap(), "static string"); - } - Ok(()) => panic!(), - } - } - - #[test] - fn test_try_panic_message_owned_str() { - match thread::spawn(move || { - panic!("owned string".to_string()); - }) - .join() - { - Err(e) => { - type T = String; - assert!(e.is::<T>()); - assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string()); - } - Ok(()) => panic!(), - } - } - - #[test] - fn test_try_panic_message_any() { - match thread::spawn(move || { - panic!(box 413u16 as Box<dyn Any + Send>); - }) - .join() - { - Err(e) => { - type T = Box<dyn Any + Send>; - assert!(e.is::<T>()); - let any = e.downcast::<T>().unwrap(); - assert!(any.is::<u16>()); - assert_eq!(*any.downcast::<u16>().unwrap(), 413); - } - Ok(()) => panic!(), - } - } - - #[test] - fn test_try_panic_message_unit_struct() { - struct Juju; - - match thread::spawn(move || panic!(Juju)).join() { - Err(ref e) if e.is::<Juju>() => {} - Err(_) | Ok(()) => panic!(), - } - } - - #[test] - fn test_park_timeout_unpark_before() { - for _ in 0..10 { - thread::current().unpark(); - thread::park_timeout(Duration::from_millis(u32::MAX as u64)); - } - } - - #[test] - fn test_park_timeout_unpark_not_called() { - for _ in 0..10 { - thread::park_timeout(Duration::from_millis(10)); - } - } - - #[test] - fn test_park_timeout_unpark_called_other_thread() { - for _ in 0..10 { - let th = thread::current(); - - let _guard = thread::spawn(move || { - super::sleep(Duration::from_millis(50)); - th.unpark(); - }); - - thread::park_timeout(Duration::from_millis(u32::MAX as u64)); - } - } - - #[test] - fn sleep_ms_smoke() { - thread::sleep(Duration::from_millis(2)); - } - - #[test] - fn test_size_of_option_thread_id() { - assert_eq!(mem::size_of::<Option<ThreadId>>(), mem::size_of::<ThreadId>()); - } - - #[test] - fn test_thread_id_equal() { - assert!(thread::current().id() == thread::current().id()); - } - - #[test] - fn test_thread_id_not_equal() { - let spawned_id = thread::spawn(|| thread::current().id()).join().unwrap(); - assert!(thread::current().id() != spawned_id); - } - - // NOTE: the corresponding test for stderr is in ui/thread-stderr, due - // to the test harness apparently interfering with stderr configuration. -} diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs new file mode 100644 index 00000000000..16ad366fc12 --- /dev/null +++ b/library/std/src/thread/tests.rs @@ -0,0 +1,262 @@ +use super::Builder; +use crate::any::Any; +use crate::mem; +use crate::result; +use crate::sync::mpsc::{channel, Sender}; +use crate::thread::{self, ThreadId}; +use crate::time::Duration; + +// !!! These tests are dangerous. If something is buggy, they will hang, !!! +// !!! instead of exiting cleanly. This might wedge the buildbots. !!! + +#[test] +fn test_unnamed_thread() { + thread::spawn(move || { + assert!(thread::current().name().is_none()); + }) + .join() + .ok() + .expect("thread panicked"); +} + +#[test] +fn test_named_thread() { + Builder::new() + .name("ada lovelace".to_string()) + .spawn(move || { + assert!(thread::current().name().unwrap() == "ada lovelace".to_string()); + }) + .unwrap() + .join() + .unwrap(); +} + +#[test] +#[should_panic] +fn test_invalid_named_thread() { + let _ = Builder::new().name("ada l\0velace".to_string()).spawn(|| {}); +} + +#[test] +fn test_run_basic() { + let (tx, rx) = channel(); + thread::spawn(move || { + tx.send(()).unwrap(); + }); + rx.recv().unwrap(); +} + +#[test] +fn test_join_panic() { + match thread::spawn(move || panic!()).join() { + result::Result::Err(_) => (), + result::Result::Ok(()) => panic!(), + } +} + +#[test] +fn test_spawn_sched() { + let (tx, rx) = channel(); + + fn f(i: i32, tx: Sender<()>) { + let tx = tx.clone(); + thread::spawn(move || { + if i == 0 { + tx.send(()).unwrap(); + } else { + f(i - 1, tx); + } + }); + } + f(10, tx); + rx.recv().unwrap(); +} + +#[test] +fn test_spawn_sched_childs_on_default_sched() { + let (tx, rx) = channel(); + + thread::spawn(move || { + thread::spawn(move || { + tx.send(()).unwrap(); + }); + }); + + rx.recv().unwrap(); +} + +fn avoid_copying_the_body<F>(spawnfn: F) +where + F: FnOnce(Box<dyn Fn() + Send>), +{ + let (tx, rx) = channel(); + + let x: Box<_> = box 1; + let x_in_parent = (&*x) as *const i32 as usize; + + spawnfn(Box::new(move || { + let x_in_child = (&*x) as *const i32 as usize; + tx.send(x_in_child).unwrap(); + })); + + let x_in_child = rx.recv().unwrap(); + assert_eq!(x_in_parent, x_in_child); +} + +#[test] +fn test_avoid_copying_the_body_spawn() { + avoid_copying_the_body(|v| { + thread::spawn(move || v()); + }); +} + +#[test] +fn test_avoid_copying_the_body_thread_spawn() { + avoid_copying_the_body(|f| { + thread::spawn(move || { + f(); + }); + }) +} + +#[test] +fn test_avoid_copying_the_body_join() { + avoid_copying_the_body(|f| { + let _ = thread::spawn(move || f()).join(); + }) +} + +#[test] +fn test_child_doesnt_ref_parent() { + // If the child refcounts the parent thread, this will stack overflow when + // climbing the thread tree to dereference each ancestor. (See #1789) + // (well, it would if the constant were 8000+ - I lowered it to be more + // valgrind-friendly. try this at home, instead..!) + const GENERATIONS: u32 = 16; + fn child_no(x: u32) -> Box<dyn Fn() + Send> { + return Box::new(move || { + if x < GENERATIONS { + thread::spawn(move || child_no(x + 1)()); + } + }); + } + thread::spawn(|| child_no(0)()); +} + +#[test] +fn test_simple_newsched_spawn() { + thread::spawn(move || {}); +} + +#[test] +fn test_try_panic_message_static_str() { + match thread::spawn(move || { + panic!("static string"); + }) + .join() + { + Err(e) => { + type T = &'static str; + assert!(e.is::<T>()); + assert_eq!(*e.downcast::<T>().unwrap(), "static string"); + } + Ok(()) => panic!(), + } +} + +#[test] +fn test_try_panic_message_owned_str() { + match thread::spawn(move || { + panic!("owned string".to_string()); + }) + .join() + { + Err(e) => { + type T = String; + assert!(e.is::<T>()); + assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string()); + } + Ok(()) => panic!(), + } +} + +#[test] +fn test_try_panic_message_any() { + match thread::spawn(move || { + panic!(box 413u16 as Box<dyn Any + Send>); + }) + .join() + { + Err(e) => { + type T = Box<dyn Any + Send>; + assert!(e.is::<T>()); + let any = e.downcast::<T>().unwrap(); + assert!(any.is::<u16>()); + assert_eq!(*any.downcast::<u16>().unwrap(), 413); + } + Ok(()) => panic!(), + } +} + +#[test] +fn test_try_panic_message_unit_struct() { + struct Juju; + + match thread::spawn(move || panic!(Juju)).join() { + Err(ref e) if e.is::<Juju>() => {} + Err(_) | Ok(()) => panic!(), + } +} + +#[test] +fn test_park_timeout_unpark_before() { + for _ in 0..10 { + thread::current().unpark(); + thread::park_timeout(Duration::from_millis(u32::MAX as u64)); + } +} + +#[test] +fn test_park_timeout_unpark_not_called() { + for _ in 0..10 { + thread::park_timeout(Duration::from_millis(10)); + } +} + +#[test] +fn test_park_timeout_unpark_called_other_thread() { + for _ in 0..10 { + let th = thread::current(); + + let _guard = thread::spawn(move || { + super::sleep(Duration::from_millis(50)); + th.unpark(); + }); + + thread::park_timeout(Duration::from_millis(u32::MAX as u64)); + } +} + +#[test] +fn sleep_ms_smoke() { + thread::sleep(Duration::from_millis(2)); +} + +#[test] +fn test_size_of_option_thread_id() { + assert_eq!(mem::size_of::<Option<ThreadId>>(), mem::size_of::<ThreadId>()); +} + +#[test] +fn test_thread_id_equal() { + assert!(thread::current().id() == thread::current().id()); +} + +#[test] +fn test_thread_id_not_equal() { + let spawned_id = thread::spawn(|| thread::current().id()).join().unwrap(); + assert!(thread::current().id() != spawned_id); +} + +// NOTE: the corresponding test for stderr is in ui/thread-stderr, due +// to the test harness apparently interfering with stderr configuration. diff --git a/library/std/src/time.rs b/library/std/src/time.rs index c8aee1da39b..73c0a7b403a 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -12,6 +12,9 @@ #![stable(feature = "time", since = "1.3.0")] +#[cfg(test)] +mod tests; + use crate::cmp; use crate::error::Error; use crate::fmt; @@ -630,172 +633,3 @@ impl FromInner<time::SystemTime> for SystemTime { SystemTime(time) } } - -#[cfg(test)] -mod tests { - use super::{Duration, Instant, SystemTime, UNIX_EPOCH}; - - macro_rules! assert_almost_eq { - ($a:expr, $b:expr) => {{ - let (a, b) = ($a, $b); - if a != b { - let (a, b) = if a > b { (a, b) } else { (b, a) }; - assert!(a - Duration::new(0, 1000) <= b, "{:?} is not almost equal to {:?}", a, b); - } - }}; - } - - #[test] - fn instant_monotonic() { - let a = Instant::now(); - let b = Instant::now(); - assert!(b >= a); - } - - #[test] - fn instant_elapsed() { - let a = Instant::now(); - a.elapsed(); - } - - #[test] - fn instant_math() { - let a = Instant::now(); - let b = Instant::now(); - println!("a: {:?}", a); - println!("b: {:?}", b); - let dur = b.duration_since(a); - println!("dur: {:?}", dur); - assert_almost_eq!(b - dur, a); - assert_almost_eq!(a + dur, b); - - let second = Duration::new(1, 0); - assert_almost_eq!(a - second + second, a); - assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - - // checked_add_duration will not panic on overflow - let mut maybe_t = Some(Instant::now()); - let max_duration = Duration::from_secs(u64::MAX); - // in case `Instant` can store `>= now + max_duration`. - for _ in 0..2 { - maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); - } - assert_eq!(maybe_t, None); - - // checked_add_duration calculates the right time and will work for another year - let year = Duration::from_secs(60 * 60 * 24 * 365); - assert_eq!(a + year, a.checked_add(year).unwrap()); - } - - #[test] - fn instant_math_is_associative() { - let now = Instant::now(); - let offset = Duration::from_millis(5); - // Changing the order of instant math shouldn't change the results, - // especially when the expression reduces to X + identity. - assert_eq!((now + offset) - now, (now - now) + offset); - } - - #[test] - #[should_panic] - fn instant_duration_since_panic() { - let a = Instant::now(); - (a - Duration::new(1, 0)).duration_since(a); - } - - #[test] - fn instant_checked_duration_since_nopanic() { - let now = Instant::now(); - let earlier = now - Duration::new(1, 0); - let later = now + Duration::new(1, 0); - assert_eq!(earlier.checked_duration_since(now), None); - assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0))); - assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0))); - } - - #[test] - fn instant_saturating_duration_since_nopanic() { - let a = Instant::now(); - let ret = (a - Duration::new(1, 0)).saturating_duration_since(a); - assert_eq!(ret, Duration::new(0, 0)); - } - - #[test] - fn system_time_math() { - let a = SystemTime::now(); - let b = SystemTime::now(); - match b.duration_since(a) { - Ok(dur) if dur == Duration::new(0, 0) => { - assert_almost_eq!(a, b); - } - Ok(dur) => { - assert!(b > a); - assert_almost_eq!(b - dur, a); - assert_almost_eq!(a + dur, b); - } - Err(dur) => { - let dur = dur.duration(); - assert!(a > b); - assert_almost_eq!(b + dur, a); - assert_almost_eq!(a - dur, b); - } - } - - let second = Duration::new(1, 0); - assert_almost_eq!(a.duration_since(a - second).unwrap(), second); - assert_almost_eq!(a.duration_since(a + second).unwrap_err().duration(), second); - - assert_almost_eq!(a - second + second, a); - assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); - let one_second_from_epoch2 = - UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); - assert_eq!(one_second_from_epoch, one_second_from_epoch2); - - // checked_add_duration will not panic on overflow - let mut maybe_t = Some(SystemTime::UNIX_EPOCH); - let max_duration = Duration::from_secs(u64::MAX); - // in case `SystemTime` can store `>= UNIX_EPOCH + max_duration`. - for _ in 0..2 { - maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); - } - assert_eq!(maybe_t, None); - - // checked_add_duration calculates the right time and will work for another year - let year = Duration::from_secs(60 * 60 * 24 * 365); - assert_eq!(a + year, a.checked_add(year).unwrap()); - } - - #[test] - fn system_time_elapsed() { - let a = SystemTime::now(); - drop(a.elapsed()); - } - - #[test] - fn since_epoch() { - let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); - let b = ts.duration_since(UNIX_EPOCH).unwrap(); - assert!(b > a); - assert_eq!(b - a, Duration::new(1, 0)); - - let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30; - - // Right now for CI this test is run in an emulator, and apparently the - // aarch64 emulator's sense of time is that we're still living in the - // 70s. This is also true for riscv (also qemu) - // - // Otherwise let's assume that we're all running computers later than - // 2000. - if !cfg!(target_arch = "aarch64") && !cfg!(target_arch = "riscv64") { - assert!(a > thirty_years); - } - - // let's assume that we're all running computers earlier than 2090. - // Should give us ~70 years to fix this! - let hundred_twenty_years = thirty_years * 4; - assert!(a < hundred_twenty_years); - } -} diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs new file mode 100644 index 00000000000..783bf49f315 --- /dev/null +++ b/library/std/src/time/tests.rs @@ -0,0 +1,165 @@ +use super::{Duration, Instant, SystemTime, UNIX_EPOCH}; + +macro_rules! assert_almost_eq { + ($a:expr, $b:expr) => {{ + let (a, b) = ($a, $b); + if a != b { + let (a, b) = if a > b { (a, b) } else { (b, a) }; + assert!(a - Duration::new(0, 1000) <= b, "{:?} is not almost equal to {:?}", a, b); + } + }}; +} + +#[test] +fn instant_monotonic() { + let a = Instant::now(); + let b = Instant::now(); + assert!(b >= a); +} + +#[test] +fn instant_elapsed() { + let a = Instant::now(); + a.elapsed(); +} + +#[test] +fn instant_math() { + let a = Instant::now(); + let b = Instant::now(); + println!("a: {:?}", a); + println!("b: {:?}", b); + let dur = b.duration_since(a); + println!("dur: {:?}", dur); + assert_almost_eq!(b - dur, a); + assert_almost_eq!(a + dur, b); + + let second = Duration::new(1, 0); + assert_almost_eq!(a - second + second, a); + assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); + + // checked_add_duration will not panic on overflow + let mut maybe_t = Some(Instant::now()); + let max_duration = Duration::from_secs(u64::MAX); + // in case `Instant` can store `>= now + max_duration`. + for _ in 0..2 { + maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); + } + assert_eq!(maybe_t, None); + + // checked_add_duration calculates the right time and will work for another year + let year = Duration::from_secs(60 * 60 * 24 * 365); + assert_eq!(a + year, a.checked_add(year).unwrap()); +} + +#[test] +fn instant_math_is_associative() { + let now = Instant::now(); + let offset = Duration::from_millis(5); + // Changing the order of instant math shouldn't change the results, + // especially when the expression reduces to X + identity. + assert_eq!((now + offset) - now, (now - now) + offset); +} + +#[test] +#[should_panic] +fn instant_duration_since_panic() { + let a = Instant::now(); + (a - Duration::new(1, 0)).duration_since(a); +} + +#[test] +fn instant_checked_duration_since_nopanic() { + let now = Instant::now(); + let earlier = now - Duration::new(1, 0); + let later = now + Duration::new(1, 0); + assert_eq!(earlier.checked_duration_since(now), None); + assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0))); + assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0))); +} + +#[test] +fn instant_saturating_duration_since_nopanic() { + let a = Instant::now(); + let ret = (a - Duration::new(1, 0)).saturating_duration_since(a); + assert_eq!(ret, Duration::new(0, 0)); +} + +#[test] +fn system_time_math() { + let a = SystemTime::now(); + let b = SystemTime::now(); + match b.duration_since(a) { + Ok(dur) if dur == Duration::new(0, 0) => { + assert_almost_eq!(a, b); + } + Ok(dur) => { + assert!(b > a); + assert_almost_eq!(b - dur, a); + assert_almost_eq!(a + dur, b); + } + Err(dur) => { + let dur = dur.duration(); + assert!(a > b); + assert_almost_eq!(b + dur, a); + assert_almost_eq!(a - dur, b); + } + } + + let second = Duration::new(1, 0); + assert_almost_eq!(a.duration_since(a - second).unwrap(), second); + assert_almost_eq!(a.duration_since(a + second).unwrap_err().duration(), second); + + assert_almost_eq!(a - second + second, a); + assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); + + let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); + let one_second_from_epoch2 = + UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); + assert_eq!(one_second_from_epoch, one_second_from_epoch2); + + // checked_add_duration will not panic on overflow + let mut maybe_t = Some(SystemTime::UNIX_EPOCH); + let max_duration = Duration::from_secs(u64::MAX); + // in case `SystemTime` can store `>= UNIX_EPOCH + max_duration`. + for _ in 0..2 { + maybe_t = maybe_t.and_then(|t| t.checked_add(max_duration)); + } + assert_eq!(maybe_t, None); + + // checked_add_duration calculates the right time and will work for another year + let year = Duration::from_secs(60 * 60 * 24 * 365); + assert_eq!(a + year, a.checked_add(year).unwrap()); +} + +#[test] +fn system_time_elapsed() { + let a = SystemTime::now(); + drop(a.elapsed()); +} + +#[test] +fn since_epoch() { + let ts = SystemTime::now(); + let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let b = ts.duration_since(UNIX_EPOCH).unwrap(); + assert!(b > a); + assert_eq!(b - a, Duration::new(1, 0)); + + let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30; + + // Right now for CI this test is run in an emulator, and apparently the + // aarch64 emulator's sense of time is that we're still living in the + // 70s. This is also true for riscv (also qemu) + // + // Otherwise let's assume that we're all running computers later than + // 2000. + if !cfg!(target_arch = "aarch64") && !cfg!(target_arch = "riscv64") { + assert!(a > thirty_years); + } + + // let's assume that we're all running computers earlier than 2090. + // Should give us ~70 years to fix this! + let hundred_twenty_years = thirty_years * 4; + assert!(a < hundred_twenty_years); +} diff --git a/src/README.md b/src/README.md index 2f8e9da179a..ef0dec1c45b 100644 --- a/src/README.md +++ b/src/README.md @@ -1,5 +1,5 @@ This directory contains the source code of the rust project, including: -- `rustc` and its tests +- The test suite - The bootstrapping build system - Various submodules for tools, like rustdoc, rls, etc. diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index c4918d7f2e7..faec2c53742 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -5,7 +5,6 @@ version = "0.0.0" edition = "2018" [lib] -name = "bootstrap" path = "lib.rs" doctest = false diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index 86de3d5c6d8..975b8be02c8 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -274,7 +274,7 @@ directory, but rather the compiler is split into three different Cargo projects: * `library/std` - the standard library * `library/test` - testing support, depends on libstd -* `src/rustc` - the actual compiler itself +* `compiler/rustc` - the actual compiler itself Each "project" has a corresponding Cargo.lock file with all dependencies, and this means that building the compiler involves running Cargo three times. The diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 54eb2e99b8f..cecc9ef75ea 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1041,15 +1041,11 @@ impl<'a> Builder<'a> { } } - // FIXME: Don't use LLD with MSVC if we're compiling libtest, since it fails to link it. - // See https://github.com/rust-lang/rust/issues/68647. - let can_use_lld = mode != Mode::Std; - - if let Some(host_linker) = self.linker(compiler.host, can_use_lld) { + if let Some(host_linker) = self.linker(compiler.host, true) { cargo.env("RUSTC_HOST_LINKER", host_linker); } - if let Some(target_linker) = self.linker(target, can_use_lld) { + if let Some(target_linker) = self.linker(target, true) { let target = crate::envify(&target.triple); cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker); } diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 5b6c327896b..aeb0d713ef0 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -8,7 +8,7 @@ fn configure(host: &[&str], target: &[&str]) -> Config { config.save_toolstates = None; config.skip_only_host_steps = false; config.dry_run = true; - config.ninja = false; + config.ninja_in_file = false; // try to avoid spurious failures in dist where we create/delete each others file let dir = config .out @@ -371,7 +371,7 @@ mod dist { let mut builder = Builder::new(&build); builder.run_step_descriptions( &Builder::get_step_descriptions(Kind::Build), - &["src/rustc".into(), "library/std".into()], + &["compiler/rustc".into(), "library/std".into()], ); let a = TargetSelection::from_user("A"); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 373e240cb8e..7814ca8e5bb 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -449,7 +449,7 @@ impl Step for Rustc { const DEFAULT: bool = false; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/rustc") + run.path("compiler/rustc") } fn make_run(run: RunConfig<'_>) { @@ -524,7 +524,7 @@ pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelec .arg("--features") .arg(builder.rustc_features()) .arg("--manifest-path") - .arg(builder.src.join("src/rustc/Cargo.toml")); + .arg(builder.src.join("compiler/rustc/Cargo.toml")); rustc_cargo_env(builder, cargo, target); } @@ -819,7 +819,7 @@ impl Step for Assemble { // Link the compiler binary itself into place let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host); - let rustc = out_dir.join(exe("rustc_binary", host)); + let rustc = out_dir.join(exe("rustc-main", host)); let bindir = sysroot.join("bin"); t!(fs::create_dir_all(&bindir)); let compiler = builder.rustc(target_compiler); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index f549de6570f..ad2f4877867 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -32,7 +32,8 @@ use serde::Deserialize; #[derive(Default)] pub struct Config { pub ccache: Option<String>, - pub ninja: bool, + /// Call Build::ninja() instead of this. + pub ninja_in_file: bool, pub verbose: usize, pub submodules: bool, pub fast_submodules: bool, @@ -450,7 +451,7 @@ impl Config { pub fn default_opts() -> Config { let mut config = Config::default(); config.llvm_optimize = true; - config.ninja = true; + config.ninja_in_file = true; config.llvm_version_check = true; config.backtrace = true; config.rust_optimize = true; @@ -606,7 +607,7 @@ impl Config { } Some(StringOrBool::Bool(false)) | None => {} } - set(&mut config.ninja, llvm.ninja); + set(&mut config.ninja_in_file, llvm.ninja); llvm_assertions = llvm.assertions; llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild); set(&mut config.llvm_optimize, llvm.optimize); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index d021feafbe4..c1022099a02 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1097,7 +1097,7 @@ impl Step for PlainSourceTarball { "Cargo.toml", "Cargo.lock", ]; - let src_dirs = ["src", "library"]; + let src_dirs = ["src", "compiler", "library"]; copy_src_dirs(builder, &builder.src, &src_dirs, &[], &plain_dst_src); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 2a8f43950db..d7f3a888edd 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -694,6 +694,7 @@ impl Step for UnstableBookGen { builder.remove_dir(&out); let mut cmd = builder.tool_cmd(Tool::UnstableBookGen); cmd.arg(builder.src.join("library")); + cmd.arg(builder.src.join("compiler")); cmd.arg(builder.src.join("src")); cmd.arg(out); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 38b3a32e3b5..2db4bb07a9f 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -385,7 +385,7 @@ Arguments: ./x.py test src/test/ui --bless ./x.py test src/test/ui --compare-mode nll - Note that `test src/test/* --stage N` does NOT depend on `build src/rustc --stage N`; + Note that `test src/test/* --stage N` does NOT depend on `build compiler/rustc --stage N`; just like `build library/std --stage N` it tests the compiler produced by the previous stage. diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 191cc5b0b64..54651214363 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -650,7 +650,7 @@ impl Build { } } else { let base = self.llvm_out(self.config.build).join("build"); - let base = if !self.config.ninja && self.config.build.contains("msvc") { + let base = if !self.ninja() && self.config.build.contains("msvc") { if self.config.llvm_optimize { if self.config.llvm_release_debuginfo { base.join("RelWithDebInfo") @@ -1328,6 +1328,43 @@ impl Build { } fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f)); } + + /// Returns if config.ninja is enabled, and checks for ninja existence, + /// exiting with a nicer error message if not. + fn ninja(&self) -> bool { + let mut cmd_finder = crate::sanity::Finder::new(); + + if self.config.ninja_in_file { + // Some Linux distros rename `ninja` to `ninja-build`. + // CMake can work with either binary name. + if cmd_finder.maybe_have("ninja-build").is_none() + && cmd_finder.maybe_have("ninja").is_none() + { + eprintln!( + " +Couldn't find required command: ninja +You should install ninja, or set ninja=false in config.toml +" + ); + std::process::exit(1); + } + } + + // If ninja isn't enabled but we're building for MSVC then we try + // doubly hard to enable it. It was realized in #43767 that the msbuild + // CMake generator for MSVC doesn't respect configuration options like + // disabling LLVM assertions, which can often be quite important! + // + // In these cases we automatically enable Ninja if we find it in the + // environment. + if !self.config.ninja_in_file && self.config.build.contains("msvc") { + if cmd_finder.maybe_have("ninja").is_some() { + return true; + } + } + + self.config.ninja_in_file + } } #[cfg(unix)] diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index e9d0c017c7b..a0c79e38f9d 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -56,7 +56,7 @@ pub fn prebuilt_llvm_config( let out_dir = builder.llvm_out(target); let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build); - if !builder.config.build.contains("msvc") || builder.config.ninja { + if !builder.config.build.contains("msvc") || builder.ninja() { llvm_config_ret_dir.push("build"); } llvm_config_ret_dir.push("bin"); @@ -363,7 +363,7 @@ fn configure_cmake( // own build directories. cfg.env("DESTDIR", ""); - if builder.config.ninja { + if builder.ninja() { cfg.generator("Ninja"); } cfg.target(&target.triple).host(&builder.config.build.triple); @@ -395,7 +395,7 @@ fn configure_cmake( // MSVC with CMake uses msbuild by default which doesn't respect these // vars that we'd otherwise configure. In that case we just skip this // entirely. - if target.contains("msvc") && !builder.config.ninja { + if target.contains("msvc") && !builder.ninja() { return; } @@ -405,7 +405,7 @@ fn configure_cmake( }; // Handle msvc + ninja + ccache specially (this is what the bots use) - if target.contains("msvc") && builder.config.ninja && builder.config.ccache.is_some() { + if target.contains("msvc") && builder.ninja() && builder.config.ccache.is_some() { let mut wrap_cc = env::current_exe().expect("failed to get cwd"); wrap_cc.set_file_name("sccache-plus-cl.exe"); diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 533b5c79777..4d6612a376a 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -20,17 +20,17 @@ use build_helper::{output, t}; use crate::config::Target; use crate::Build; -struct Finder { +pub struct Finder { cache: HashMap<OsString, Option<PathBuf>>, path: OsString, } impl Finder { - fn new() -> Self { + pub fn new() -> Self { Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() } } - fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> { + pub fn maybe_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> Option<PathBuf> { let cmd: OsString = cmd.as_ref().into(); let path = &self.path; self.cache @@ -54,7 +54,7 @@ impl Finder { .clone() } - fn must_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> PathBuf { + pub fn must_have<S: AsRef<OsStr>>(&mut self, cmd: S) -> PathBuf { self.maybe_have(&cmd).unwrap_or_else(|| { panic!("\n\ncouldn't find required command: {:?}\n\n", cmd.as_ref()); }) @@ -95,38 +95,6 @@ pub fn check(build: &mut Build) { cmd_finder.must_have("cmake"); } - // Ninja is currently only used for LLVM itself. - if building_llvm { - if build.config.ninja { - // Some Linux distros rename `ninja` to `ninja-build`. - // CMake can work with either binary name. - if cmd_finder.maybe_have("ninja-build").is_none() - && cmd_finder.maybe_have("ninja").is_none() - { - eprintln!( - " -Couldn't find required command: ninja -You should install ninja, or set ninja=false in config.toml -" - ); - std::process::exit(1); - } - } - - // If ninja isn't enabled but we're building for MSVC then we try - // doubly hard to enable it. It was realized in #43767 that the msbuild - // CMake generator for MSVC doesn't respect configuration options like - // disabling LLVM assertions, which can often be quite important! - // - // In these cases we automatically enable Ninja if we find it in the - // environment. - if !build.config.ninja && build.config.build.contains("msvc") { - if cmd_finder.maybe_have("ninja").is_some() { - build.config.ninja = true; - } - } - } - build.config.python = build .config .python diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ac833a55d4c..a7c9b99f45f 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -734,7 +734,7 @@ impl Step for Tidy { /// for the `dev` or `nightly` channels. fn run(self, builder: &Builder<'_>) { let mut cmd = builder.tool_cmd(Tool::Tidy); - cmd.arg(builder.src.join("src")); + cmd.arg(&builder.src); cmd.arg(&builder.initial_cargo); if builder.is_verbose() { cmd.arg("--verbose"); diff --git a/src/build_helper/Cargo.toml b/src/build_helper/Cargo.toml index 04c7820b456..2420f1b7f18 100644 --- a/src/build_helper/Cargo.toml +++ b/src/build_helper/Cargo.toml @@ -5,5 +5,4 @@ authors = ["The Rust Project Developers"] edition = "2018" [lib] -name = "build_helper" path = "lib.rs" diff --git a/src/doc/book b/src/doc/book -Subproject c0a6a61b8205da14ac955425f74258ffd8ee065 +Subproject e5ed97128302d5fa45dbac0e64426bc7649a558 diff --git a/src/doc/edition-guide b/src/doc/edition-guide -Subproject bd6e4a9f59c5c1545f572266af77f5c7a5bad6d +Subproject 81f16863014de60b53de401d71ff904d163ee03 diff --git a/src/doc/reference b/src/doc/reference -Subproject 1b6c4b0afab97c0230433466c97167bbbe8445f +Subproject 25391dba46262f882fa846beefaff54a966a8fa diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject 80a10e22140e28392b99d24ed02f4c6d8cb770a +Subproject 19f0a0372af497b34369cf182d9d16156cab296 diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 7b0280d5b78..bed10ca16d3 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -44,13 +44,13 @@ incremental builds the default is 256 which allows caching to be more granular. ## control-flow-guard -This flag controls whether LLVM enables the Windows [Control Flow -Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) -platform security feature. This flag is currently ignored for non-Windows targets. +This flag controls whether LLVM enables the Windows [Control Flow +Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) +platform security feature. This flag is currently ignored for non-Windows targets. It takes one of the following values: * `y`, `yes`, `on`, `checks`, or no value: enable Control Flow Guard. -* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this +* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this should only be used for testing purposes as it does not provide security enforcement). * `n`, `no`, `off`: do not enable Control Flow Guard (the default). @@ -200,6 +200,18 @@ the following values: An example of when this flag might be useful is when trying to construct code coverage metrics. +## link-self-contained + +On targets that support it this flag controls whether the linker will use libraries and objects +shipped with Rust instead or those in the system. +It takes one of the following values: + +* no value: rustc will use heuristic to disable self-contained mode if system has necessary tools. +* `y`, `yes`, `on`: use only libraries/objects shipped with Rust. +* `n`, `no`, or `off`: rely on the user or the linker to provide non-Rust libraries/objects. + +This allows overriding cases when detection fails or user wants to use shipped libraries. + ## linker This flag controls which linker `rustc` invokes to link your code. It takes a diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index d1d6bc1c1fe..8e2869fef55 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -51,7 +51,7 @@ warning: missing documentation for a function ## missing_doc_code_examples -This lint is **allowed by default**. It detects when a documentation block +This lint is **allowed by default** and is **nightly-only**. It detects when a documentation block is missing a code example. For example: ```rust diff --git a/src/librustc_ast/Cargo.toml b/src/librustc_ast/Cargo.toml deleted file mode 100644 index 73c5e33753f..00000000000 --- a/src/librustc_ast/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_ast" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_ast" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_serialize = { path = "../librustc_serialize" } -tracing = "0.1" -rustc_span = { path = "../librustc_span" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_index = { path = "../librustc_index" } -rustc_lexer = { path = "../librustc_lexer" } -rustc_macros = { path = "../librustc_macros" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -bitflags = "1.2.1" diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml deleted file mode 100644 index bf7e69a31ab..00000000000 --- a/src/librustc_ast_lowering/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_ast_lowering" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_ast_lowering" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_arena = { path = "../librustc_arena" } -tracing = "0.1" -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_hir = { path = "../librustc_hir" } -rustc_target = { path = "../librustc_target" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_index = { path = "../librustc_index" } -rustc_span = { path = "../librustc_span" } -rustc_errors = { path = "../librustc_errors" } -rustc_session = { path = "../librustc_session" } -rustc_ast = { path = "../librustc_ast" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml deleted file mode 100644 index 6db9bce3164..00000000000 --- a/src/librustc_ast_passes/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_ast_passes" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_ast_passes" -path = "lib.rs" - -[dependencies] -itertools = "0.8" -tracing = "0.1" -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } -rustc_parse = { path = "../librustc_parse" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml deleted file mode 100644 index d26205c791d..00000000000 --- a/src/librustc_ast_pretty/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_ast_pretty" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_ast_pretty" -path = "lib.rs" -doctest = false - -[dependencies] -tracing = "0.1" -rustc_span = { path = "../librustc_span" } -rustc_ast = { path = "../librustc_ast" } -rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml deleted file mode 100644 index 35bdf747f08..00000000000 --- a/src/librustc_attr/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_attr" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_attr" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_errors = { path = "../librustc_errors" } -rustc_span = { path = "../librustc_span" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_feature = { path = "../librustc_feature" } -rustc_lexer = { path = "../librustc_lexer" } -rustc_macros = { path = "../librustc_macros" } -rustc_session = { path = "../librustc_session" } -rustc_ast = { path = "../librustc_ast" } -version_check = "0.9" diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml deleted file mode 100644 index dee6fed317e..00000000000 --- a/src/librustc_builtin_macros/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_builtin_macros" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_builtin_macros" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_parse_format = { path = "../librustc_parse_format" } -tracing = "0.1" -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } -rustc_parse = { path = "../librustc_parse" } -rustc_target = { path = "../librustc_target" } -rustc_session = { path = "../librustc_session" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_ast = { path = "../librustc_ast" } -rustc_expand = { path = "../librustc_expand" } -rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml deleted file mode 100644 index d8ccaf16e28..00000000000 --- a/src/librustc_codegen_llvm/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_codegen_llvm" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_codegen_llvm" -path = "lib.rs" -test = false -doctest = false - -[dependencies] -bitflags = "1.0" -libc = "0.2" -measureme = "0.7.1" -snap = "1" -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc-demangle = "0.1" -rustc_attr = { path = "../librustc_attr" } -rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } -rustc_fs_util = { path = "../librustc_fs_util" } -rustc_hir = { path = "../librustc_hir" } -rustc_incremental = { path = "../librustc_incremental" } -rustc_index = { path = "../librustc_index" } -rustc_llvm = { path = "../librustc_llvm" } -rustc_session = { path = "../librustc_session" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_target = { path = "../librustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml deleted file mode 100644 index 5707d3cd0ed..00000000000 --- a/src/librustc_codegen_ssa/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_codegen_ssa" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_codegen_ssa" -path = "lib.rs" -test = false - -[dependencies] -bitflags = "1.2.1" -cc = "1.0.1" -num_cpus = "1.0" -memmap = "0.7" -tracing = "0.1" -libc = "0.2.50" -jobserver = "0.1.11" -tempfile = "3.1" -pathdiff = "0.2.0" - -rustc_serialize = { path = "../librustc_serialize" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -rustc_middle = { path = "../librustc_middle" } -rustc_apfloat = { path = "../librustc_apfloat" } -rustc_attr = { path = "../librustc_attr" } -rustc_symbol_mangling = { path = "../librustc_symbol_mangling" } -rustc_data_structures = { path = "../librustc_data_structures"} -rustc_errors = { path = "../librustc_errors" } -rustc_fs_util = { path = "../librustc_fs_util" } -rustc_hir = { path = "../librustc_hir" } -rustc_incremental = { path = "../librustc_incremental" } -rustc_index = { path = "../librustc_index" } -rustc_macros = { path = "../librustc_macros" } -rustc_target = { path = "../librustc_target" } -rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_data_structures/jobserver.rs b/src/librustc_data_structures/jobserver.rs deleted file mode 100644 index a811c88839d..00000000000 --- a/src/librustc_data_structures/jobserver.rs +++ /dev/null @@ -1,42 +0,0 @@ -pub use jobserver_crate::Client; -use lazy_static::lazy_static; - -lazy_static! { - // We can only call `from_env` once per process - - // Note that this is unsafe because it may misinterpret file descriptors - // on Unix as jobserver file descriptors. We hopefully execute this near - // the beginning of the process though to ensure we don't get false - // positives, or in other words we try to execute this before we open - // any file descriptors ourselves. - // - // Pick a "reasonable maximum" if we don't otherwise have - // a jobserver in our environment, capping out at 32 so we - // don't take everything down by hogging the process run queue. - // The fixed number is used to have deterministic compilation - // across machines. - // - // Also note that we stick this in a global because there could be - // multiple rustc instances in this process, and the jobserver is - // per-process. - static ref GLOBAL_CLIENT: Client = unsafe { - Client::from_env().unwrap_or_else(|| { - let client = Client::new(32).expect("failed to create jobserver"); - // Acquire a token for the main thread which we can release later - client.acquire_raw().ok(); - client - }) - }; -} - -pub fn client() -> Client { - GLOBAL_CLIENT.clone() -} - -pub fn acquire_thread() { - GLOBAL_CLIENT.acquire_raw().ok(); -} - -pub fn release_thread() { - GLOBAL_CLIENT.release_raw().ok(); -} diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml deleted file mode 100644 index 46331c63113..00000000000 --- a/src/librustc_driver/Cargo.toml +++ /dev/null @@ -1,43 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_driver" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_driver" -path = "lib.rs" -crate-type = ["dylib"] - -[dependencies] -lazy_static = "1.0" -libc = "0.2" -tracing = { version = "0.1.18", features = ["release_max_level_info"] } -tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } -rustc_middle = { path = "../librustc_middle" } -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_target = { path = "../librustc_target" } -rustc_lint = { path = "../librustc_lint" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } -rustc_hir = { path = "../librustc_hir" } -rustc_hir_pretty = { path = "../librustc_hir_pretty" } -rustc_metadata = { path = "../librustc_metadata" } -rustc_mir = { path = "../librustc_mir" } -rustc_parse = { path = "../librustc_parse" } -rustc_plugin_impl = { path = "../librustc_plugin_impl" } -rustc_save_analysis = { path = "../librustc_save_analysis" } -rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } -rustc_session = { path = "../librustc_session" } -rustc_error_codes = { path = "../librustc_error_codes" } -rustc_interface = { path = "../librustc_interface" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } - -[features] -llvm = ['rustc_interface/llvm'] diff --git a/src/librustc_expand/Cargo.toml b/src/librustc_expand/Cargo.toml deleted file mode 100644 index 55a1862971b..00000000000 --- a/src/librustc_expand/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_expand" -version = "0.0.0" -edition = "2018" -build = false - -[lib] -name = "rustc_expand" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_serialize = { path = "../librustc_serialize" } -tracing = "0.1" -rustc_span = { path = "../librustc_span" } -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_ast_passes = { path = "../librustc_ast_passes" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } -rustc_macros = { path = "../librustc_macros" } -rustc_lexer = { path = "../librustc_lexer" } -rustc_parse = { path = "../librustc_parse" } -rustc_session = { path = "../librustc_session" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_expand/parse/lexer/tests.rs b/src/librustc_expand/parse/lexer/tests.rs deleted file mode 100644 index 87184444283..00000000000 --- a/src/librustc_expand/parse/lexer/tests.rs +++ /dev/null @@ -1,252 +0,0 @@ -use rustc_ast::ast::AttrStyle; -use rustc_ast::token::{self, CommentKind, Token, TokenKind}; -use rustc_data_structures::sync::Lrc; -use rustc_errors::{emitter::EmitterWriter, Handler}; -use rustc_parse::lexer::StringReader; -use rustc_session::parse::ParseSess; -use rustc_span::source_map::{FilePathMapping, SourceMap}; -use rustc_span::symbol::Symbol; -use rustc_span::with_default_session_globals; -use rustc_span::{BytePos, Span}; - -use std::io; -use std::path::PathBuf; - -fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess { - let emitter = EmitterWriter::new( - Box::new(io::sink()), - Some(sm.clone()), - false, - false, - false, - None, - false, - ); - ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm) -} - -// Creates a string reader for the given string. -fn setup<'a>(sm: &SourceMap, sess: &'a ParseSess, teststr: String) -> StringReader<'a> { - let sf = sm.new_source_file(PathBuf::from(teststr.clone()).into(), teststr); - StringReader::new(sess, sf, None) -} - -#[test] -fn t1() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - let mut string_reader = setup( - &sm, - &sh, - "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_string(), - ); - assert_eq!(string_reader.next_token(), token::Comment); - assert_eq!(string_reader.next_token(), token::Whitespace); - let tok1 = string_reader.next_token(); - let tok2 = Token::new(mk_ident("fn"), Span::with_root_ctxt(BytePos(21), BytePos(23))); - assert_eq!(tok1.kind, tok2.kind); - assert_eq!(tok1.span, tok2.span); - assert_eq!(string_reader.next_token(), token::Whitespace); - // Read another token. - let tok3 = string_reader.next_token(); - assert_eq!(string_reader.pos(), BytePos(28)); - let tok4 = Token::new(mk_ident("main"), Span::with_root_ctxt(BytePos(24), BytePos(28))); - assert_eq!(tok3.kind, tok4.kind); - assert_eq!(tok3.span, tok4.span); - - assert_eq!(string_reader.next_token(), token::OpenDelim(token::Paren)); - assert_eq!(string_reader.pos(), BytePos(29)) - }) -} - -// Checks that the given reader produces the desired stream -// of tokens (stop checking after exhausting `expected`). -fn check_tokenization(mut string_reader: StringReader<'_>, expected: Vec<TokenKind>) { - for expected_tok in &expected { - assert_eq!(&string_reader.next_token(), expected_tok); - } -} - -// Makes the identifier by looking up the string in the interner. -fn mk_ident(id: &str) -> TokenKind { - token::Ident(Symbol::intern(id), false) -} - -fn mk_lit(kind: token::LitKind, symbol: &str, suffix: Option<&str>) -> TokenKind { - TokenKind::lit(kind, Symbol::intern(symbol), suffix.map(Symbol::intern)) -} - -#[test] -fn doublecolon_parsing() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization( - setup(&sm, &sh, "a b".to_string()), - vec![mk_ident("a"), token::Whitespace, mk_ident("b")], - ); - }) -} - -#[test] -fn doublecolon_parsing_2() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization( - setup(&sm, &sh, "a::b".to_string()), - vec![mk_ident("a"), token::Colon, token::Colon, mk_ident("b")], - ); - }) -} - -#[test] -fn doublecolon_parsing_3() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization( - setup(&sm, &sh, "a ::b".to_string()), - vec![mk_ident("a"), token::Whitespace, token::Colon, token::Colon, mk_ident("b")], - ); - }) -} - -#[test] -fn doublecolon_parsing_4() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - check_tokenization( - setup(&sm, &sh, "a:: b".to_string()), - vec![mk_ident("a"), token::Colon, token::Colon, token::Whitespace, mk_ident("b")], - ); - }) -} - -#[test] -fn character_a() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token(), mk_lit(token::Char, "a", None),); - }) -} - -#[test] -fn character_space() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token(), mk_lit(token::Char, " ", None),); - }) -} - -#[test] -fn character_escaped() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!( - setup(&sm, &sh, "'\\n'".to_string()).next_token(), - mk_lit(token::Char, "\\n", None), - ); - }) -} - -#[test] -fn lifetime_name() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!( - setup(&sm, &sh, "'abc".to_string()).next_token(), - token::Lifetime(Symbol::intern("'abc")), - ); - }) -} - -#[test] -fn raw_string() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - assert_eq!( - setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token(), - mk_lit(token::StrRaw(3), "\"#a\\b\x00c\"", None), - ); - }) -} - -#[test] -fn literal_suffixes() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - macro_rules! test { - ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ - assert_eq!( - setup(&sm, &sh, format!("{}suffix", $input)).next_token(), - mk_lit(token::$tok_type, $tok_contents, Some("suffix")), - ); - // with a whitespace separator - assert_eq!( - setup(&sm, &sh, format!("{} suffix", $input)).next_token(), - mk_lit(token::$tok_type, $tok_contents, None), - ); - }}; - } - - test!("'a'", Char, "a"); - test!("b'a'", Byte, "a"); - test!("\"a\"", Str, "a"); - test!("b\"a\"", ByteStr, "a"); - test!("1234", Integer, "1234"); - test!("0b101", Integer, "0b101"); - test!("0xABC", Integer, "0xABC"); - test!("1.0", Float, "1.0"); - test!("1.0e10", Float, "1.0e10"); - - assert_eq!( - setup(&sm, &sh, "2us".to_string()).next_token(), - mk_lit(token::Integer, "2", Some("us")), - ); - assert_eq!( - setup(&sm, &sh, "r###\"raw\"###suffix".to_string()).next_token(), - mk_lit(token::StrRaw(3), "raw", Some("suffix")), - ); - assert_eq!( - setup(&sm, &sh, "br###\"raw\"###suffix".to_string()).next_token(), - mk_lit(token::ByteStrRaw(3), "raw", Some("suffix")), - ); - }) -} - -#[test] -fn nested_block_comments() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string()); - assert_eq!(lexer.next_token(), token::Comment); - assert_eq!(lexer.next_token(), mk_lit(token::Char, "a", None)); - }) -} - -#[test] -fn crlf_comments() { - with_default_session_globals(|| { - let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let sh = mk_sess(sm.clone()); - let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string()); - let comment = lexer.next_token(); - assert_eq!(comment.kind, token::Comment); - assert_eq!((comment.span.lo(), comment.span.hi()), (BytePos(0), BytePos(7))); - assert_eq!(lexer.next_token(), token::Whitespace); - assert_eq!( - lexer.next_token(), - token::DocComment(CommentKind::Line, AttrStyle::Outer, Symbol::intern(" test")) - ); - }) -} diff --git a/src/librustc_feature/Cargo.toml b/src/librustc_feature/Cargo.toml deleted file mode 100644 index 96fd15ef304..00000000000 --- a/src/librustc_feature/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_feature" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_feature" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_data_structures = { path = "../librustc_data_structures" } -lazy_static = "1.0.0" -rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml deleted file mode 100644 index a473a8edcdd..00000000000 --- a/src/librustc_hir/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_hir" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_hir" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_target = { path = "../librustc_target" } -rustc_macros = { path = "../librustc_macros" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_index = { path = "../librustc_index" } -rustc_span = { path = "../librustc_span" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_ast = { path = "../librustc_ast" } -lazy_static = "1" -tracing = "0.1" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_hir_pretty/Cargo.toml b/src/librustc_hir_pretty/Cargo.toml deleted file mode 100644 index ccd3e9b6e43..00000000000 --- a/src/librustc_hir_pretty/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_hir_pretty" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_hir_pretty" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_hir = { path = "../librustc_hir" } -rustc_target = { path = "../librustc_target" } -rustc_span = { path = "../librustc_span" } -rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml deleted file mode 100644 index 1f7e3725412..00000000000 --- a/src/librustc_incremental/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_incremental" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_incremental" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_graphviz = { path = "../librustc_graphviz" } -tracing = "0.1" -rand = "0.7" -rustc_middle = { path = "../librustc_middle" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_hir = { path = "../librustc_hir" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_ast = { path = "../librustc_ast" } -rustc_macros = { path = "../librustc_macros" } -rustc_span = { path = "../librustc_span" } -rustc_fs_util = { path = "../librustc_fs_util" } -rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_infer/Cargo.toml b/src/librustc_infer/Cargo.toml deleted file mode 100644 index e1698d66323..00000000000 --- a/src/librustc_infer/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_infer" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_infer" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_graphviz = { path = "../librustc_graphviz" } -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_index = { path = "../librustc_index" } -rustc_macros = { path = "../librustc_macros" } -rustc_session = { path = "../librustc_session" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_span = { path = "../librustc_span" } -rustc_target = { path = "../librustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml deleted file mode 100644 index b9837c6ade9..00000000000 --- a/src/librustc_interface/Cargo.toml +++ /dev/null @@ -1,57 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_interface" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_interface" -path = "lib.rs" -doctest = false - -[dependencies] -libc = "0.2" -tracing = "0.1" -rayon = { version = "0.3.0", package = "rustc-rayon" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_ast = { path = "../librustc_ast" } -rustc_attr = { path = "../librustc_attr" } -rustc_builtin_macros = { path = "../librustc_builtin_macros" } -rustc_expand = { path = "../librustc_expand" } -rustc_parse = { path = "../librustc_parse" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_middle = { path = "../librustc_middle" } -rustc_ast_lowering = { path = "../librustc_ast_lowering" } -rustc_ast_passes = { path = "../librustc_ast_passes" } -rustc_incremental = { path = "../librustc_incremental" } -rustc_traits = { path = "../librustc_traits" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } -rustc_symbol_mangling = { path = "../librustc_symbol_mangling" } -rustc_codegen_llvm = { path = "../librustc_codegen_llvm", optional = true } -rustc_hir = { path = "../librustc_hir" } -rustc_metadata = { path = "../librustc_metadata" } -rustc_mir = { path = "../librustc_mir" } -rustc_mir_build = { path = "../librustc_mir_build" } -rustc_passes = { path = "../librustc_passes" } -rustc_typeck = { path = "../librustc_typeck" } -rustc_lint = { path = "../librustc_lint" } -rustc_errors = { path = "../librustc_errors" } -rustc_plugin_impl = { path = "../librustc_plugin_impl" } -rustc_privacy = { path = "../librustc_privacy" } -rustc_resolve = { path = "../librustc_resolve" } -rustc_trait_selection = { path = "../librustc_trait_selection" } -rustc_ty = { path = "../librustc_ty" } -tempfile = "3.0.5" -once_cell = "1" - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["libloaderapi"] } - -[dev-dependencies] -rustc_target = { path = "../librustc_target" } - -[features] -llvm = ['rustc_codegen_llvm'] diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs deleted file mode 100644 index a1ea5ceb1f6..00000000000 --- a/src/librustc_lexer/src/tests.rs +++ /dev/null @@ -1,167 +0,0 @@ -use super::*; - -use expect_test::{expect, Expect}; - -fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) { - let s = &format!("r{}", s); - let mut cursor = Cursor::new(s); - cursor.bump(); - let (n_hashes, err) = cursor.raw_double_quoted_string(0); - assert_eq!(n_hashes, expected_hashes); - assert_eq!(err, expected_err); -} - -#[test] -fn test_naked_raw_str() { - check_raw_str(r#""abc""#, 0, None); -} - -#[test] -fn test_raw_no_start() { - check_raw_str(r##""abc"#"##, 0, None); -} - -#[test] -fn test_too_many_terminators() { - // this error is handled in the parser later - check_raw_str(r###"#"abc"##"###, 1, None); -} - -#[test] -fn test_unterminated() { - check_raw_str( - r#"#"abc"#, - 1, - Some(RawStrError::NoTerminator { expected: 1, found: 0, possible_terminator_offset: None }), - ); - check_raw_str( - r###"##"abc"#"###, - 2, - Some(RawStrError::NoTerminator { - expected: 2, - found: 1, - possible_terminator_offset: Some(7), - }), - ); - // We're looking for "# not just any # - check_raw_str( - r###"##"abc#"###, - 2, - Some(RawStrError::NoTerminator { expected: 2, found: 0, possible_terminator_offset: None }), - ) -} - -#[test] -fn test_invalid_start() { - check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' })); -} - -#[test] -fn test_unterminated_no_pound() { - // https://github.com/rust-lang/rust/issues/70677 - check_raw_str( - r#"""#, - 0, - Some(RawStrError::NoTerminator { expected: 0, found: 0, possible_terminator_offset: None }), - ); -} - -#[test] -fn test_valid_shebang() { - // https://github.com/rust-lang/rust/issues/70528 - let input = "#!/usr/bin/rustrun\nlet x = 5;"; - assert_eq!(strip_shebang(input), Some(18)); -} - -#[test] -fn test_invalid_shebang_valid_rust_syntax() { - // https://github.com/rust-lang/rust/issues/70528 - let input = "#! [bad_attribute]"; - assert_eq!(strip_shebang(input), None); -} - -#[test] -fn test_shebang_second_line() { - // Because shebangs are interpreted by the kernel, they must be on the first line - let input = "\n#!/bin/bash"; - assert_eq!(strip_shebang(input), None); -} - -#[test] -fn test_shebang_space() { - let input = "#! /bin/bash"; - assert_eq!(strip_shebang(input), Some(input.len())); -} - -#[test] -fn test_shebang_empty_shebang() { - let input = "#! \n[attribute(foo)]"; - assert_eq!(strip_shebang(input), None); -} - -#[test] -fn test_invalid_shebang_comment() { - let input = "#!//bin/ami/a/comment\n["; - assert_eq!(strip_shebang(input), None) -} - -#[test] -fn test_invalid_shebang_another_comment() { - let input = "#!/*bin/ami/a/comment*/\n[attribute"; - assert_eq!(strip_shebang(input), None) -} - -#[test] -fn test_shebang_valid_rust_after() { - let input = "#!/*bin/ami/a/comment*/\npub fn main() {}"; - assert_eq!(strip_shebang(input), Some(23)) -} - -#[test] -fn test_shebang_followed_by_attrib() { - let input = "#!/bin/rust-scripts\n#![allow_unused(true)]"; - assert_eq!(strip_shebang(input), Some(19)); -} - -fn check_lexing(src: &str, expect: Expect) { - let actual: String = tokenize(src).map(|token| format!("{:?}\n", token)).collect(); - expect.assert_eq(&actual) -} - -#[test] -fn comment_flavors() { - check_lexing( - r" -// line -//// line as well -/// outer doc line -//! inner doc line -/* block */ -/**/ -/*** also block */ -/** outer doc block */ -/*! inner doc block */ -", - expect![[r#" - Token { kind: Whitespace, len: 1 } - Token { kind: LineComment { doc_style: None }, len: 7 } - Token { kind: Whitespace, len: 1 } - Token { kind: LineComment { doc_style: None }, len: 17 } - Token { kind: Whitespace, len: 1 } - Token { kind: LineComment { doc_style: Some(Outer) }, len: 18 } - Token { kind: Whitespace, len: 1 } - Token { kind: LineComment { doc_style: Some(Inner) }, len: 18 } - Token { kind: Whitespace, len: 1 } - Token { kind: BlockComment { doc_style: None, terminated: true }, len: 11 } - Token { kind: Whitespace, len: 1 } - Token { kind: BlockComment { doc_style: None, terminated: true }, len: 4 } - Token { kind: Whitespace, len: 1 } - Token { kind: BlockComment { doc_style: None, terminated: true }, len: 18 } - Token { kind: Whitespace, len: 1 } - Token { kind: BlockComment { doc_style: Some(Outer), terminated: true }, len: 22 } - Token { kind: Whitespace, len: 1 } - Token { kind: BlockComment { doc_style: Some(Inner), terminated: true }, len: 22 } - Token { kind: Whitespace, len: 1 } - "#]], - ) -} diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml deleted file mode 100644 index d779f15f19a..00000000000 --- a/src/librustc_lint/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_lint" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_lint" -path = "lib.rs" - -[dependencies] -tracing = "0.1" -unicode-security = "0.0.5" -rustc_middle = { path = "../librustc_middle" } -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_attr = { path = "../librustc_attr" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_target = { path = "../librustc_target" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_feature = { path = "../librustc_feature" } -rustc_index = { path = "../librustc_index" } -rustc_session = { path = "../librustc_session" } -rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 9f2711eec10..7120f2e991a 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -5,7 +5,6 @@ version = "0.0.0" edition = "2018" [lib] -name = "rustc_llvm" path = "lib.rs" [features] diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml deleted file mode 100644 index 76e11bd689c..00000000000 --- a/src/librustc_metadata/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_metadata" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_metadata" -path = "lib.rs" -doctest = false - -[dependencies] -libc = "0.2" -snap = "1" -tracing = "0.1" -memmap = "0.7" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_middle = { path = "../librustc_middle" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_hir_pretty = { path = "../librustc_hir_pretty" } -rustc_target = { path = "../librustc_target" } -rustc_index = { path = "../librustc_index" } -rustc_macros = { path = "../librustc_macros" } -rustc_serialize = { path = "../librustc_serialize" } -stable_deref_trait = "1.0.0" -rustc_ast = { path = "../librustc_ast" } -rustc_expand = { path = "../librustc_expand" } -rustc_span = { path = "../librustc_span" } -rustc_session = { path = "../librustc_session" } - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] } diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml deleted file mode 100644 index 311126361bc..00000000000 --- a/src/librustc_middle/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_middle" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_middle" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_arena = { path = "../librustc_arena" } -bitflags = "1.2.1" -tracing = "0.1" -rustc-rayon-core = "0.3.0" -polonius-engine = "0.12.0" -rustc_apfloat = { path = "../librustc_apfloat" } -rustc_attr = { path = "../librustc_attr" } -rustc_feature = { path = "../librustc_feature" } -rustc_hir = { path = "../librustc_hir" } -rustc_target = { path = "../librustc_target" } -rustc_macros = { path = "../librustc_macros" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_query_system = { path = "../librustc_query_system" } -rustc_errors = { path = "../librustc_errors" } -rustc_index = { path = "../librustc_index" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -byteorder = { version = "1.3" } -chalk-ir = "0.14.0" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -measureme = "0.7.1" -rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_middle/ty/print/obsolete.rs b/src/librustc_middle/ty/print/obsolete.rs deleted file mode 100644 index 2ea7cd2a6dc..00000000000 --- a/src/librustc_middle/ty/print/obsolete.rs +++ /dev/null @@ -1,251 +0,0 @@ -//! Allows for producing a unique string key for a mono item. -//! These keys are used by the handwritten auto-tests, so they need to be -//! predictable and human-readable. -//! -//! Note: A lot of this could looks very similar to what's already in `ty::print`. -//! FIXME(eddyb) implement a custom `PrettyPrinter` for this. - -use crate::bug; -use crate::ty::subst::SubstsRef; -use crate::ty::{self, Const, Instance, Ty, TyCtxt}; -use rustc_hir as hir; -use rustc_hir::def_id::DefId; -use std::fmt::Write; -use std::iter; - -/// Same as `unique_type_name()` but with the result pushed onto the given -/// `output` parameter. -pub struct DefPathBasedNames<'tcx> { - tcx: TyCtxt<'tcx>, - omit_disambiguators: bool, - omit_local_crate_name: bool, -} - -impl DefPathBasedNames<'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, omit_disambiguators: bool, omit_local_crate_name: bool) -> Self { - DefPathBasedNames { tcx, omit_disambiguators, omit_local_crate_name } - } - - // Pushes the type name of the specified type to the provided string. - // If `debug` is true, printing normally unprintable types is allowed - // (e.g. `ty::GeneratorWitness`). This parameter should only be set when - // this method is being used for logging purposes (e.g. with `debug!` or `info!`) - // When being used for codegen purposes, `debug` should be set to `false` - // in order to catch unexpected types that should never end up in a type name. - pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { - match t.kind { - ty::Bool => output.push_str("bool"), - ty::Char => output.push_str("char"), - ty::Str => output.push_str("str"), - ty::Never => output.push_str("!"), - ty::Int(ty) => output.push_str(ty.name_str()), - ty::Uint(ty) => output.push_str(ty.name_str()), - ty::Float(ty) => output.push_str(ty.name_str()), - ty::Adt(adt_def, substs) => { - self.push_def_path(adt_def.did, output); - self.push_generic_params(substs, iter::empty(), output, debug); - } - ty::Tuple(component_types) => { - output.push('('); - for component_type in component_types { - self.push_type_name(component_type.expect_ty(), output, debug); - output.push_str(", "); - } - if !component_types.is_empty() { - output.pop(); - output.pop(); - } - output.push(')'); - } - ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => { - output.push('*'); - match mutbl { - hir::Mutability::Not => output.push_str("const "), - hir::Mutability::Mut => output.push_str("mut "), - } - - self.push_type_name(inner_type, output, debug); - } - ty::Ref(_, inner_type, mutbl) => { - output.push('&'); - output.push_str(mutbl.prefix_str()); - - self.push_type_name(inner_type, output, debug); - } - ty::Array(inner_type, len) => { - output.push('['); - self.push_type_name(inner_type, output, debug); - let len = len.eval_usize(self.tcx, ty::ParamEnv::reveal_all()); - write!(output, "; {}", len).unwrap(); - output.push(']'); - } - ty::Slice(inner_type) => { - output.push('['); - self.push_type_name(inner_type, output, debug); - output.push(']'); - } - ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - self.push_def_path(principal.def_id(), output); - self.push_generic_params( - principal.skip_binder().substs, - trait_data.projection_bounds(), - output, - debug, - ); - } else { - output.push_str("dyn '_"); - } - } - ty::Foreign(did) => self.push_def_path(did, output), - ty::FnDef(..) | ty::FnPtr(_) => { - let sig = t.fn_sig(self.tcx); - output.push_str(sig.unsafety().prefix_str()); - - let abi = sig.abi(); - if abi != ::rustc_target::spec::abi::Abi::Rust { - output.push_str("extern \""); - output.push_str(abi.name()); - output.push_str("\" "); - } - - output.push_str("fn("); - - let sig = - self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - - if !sig.inputs().is_empty() { - for ¶meter_type in sig.inputs() { - self.push_type_name(parameter_type, output, debug); - output.push_str(", "); - } - output.pop(); - output.pop(); - } - - if sig.c_variadic { - if !sig.inputs().is_empty() { - output.push_str(", ..."); - } else { - output.push_str("..."); - } - } - - output.push(')'); - - if !sig.output().is_unit() { - output.push_str(" -> "); - self.push_type_name(sig.output(), output, debug); - } - } - ty::Generator(def_id, substs, _) | ty::Closure(def_id, substs) => { - self.push_def_path(def_id, output); - let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); - let substs = substs.truncate_to(self.tcx, generics); - self.push_generic_params(substs, iter::empty(), output, debug); - } - ty::Param(_) => { - output.push_str(&t.to_string()); - } - ty::Error(_) - | ty::Bound(..) - | ty::Infer(_) - | ty::Placeholder(..) - | ty::Projection(..) - | ty::GeneratorWitness(_) - | ty::Opaque(..) => { - if debug { - output.push_str(&format!("`{:?}`", t)); - } else { - bug!( - "DefPathBasedNames: trying to create type name for unexpected type: {:?}", - t, - ); - } - } - } - } - - // Pushes the the name of the specified const to the provided string. - // If `debug` is true, the unprintable types of constants will be printed with `fmt::Debug` - // (see `push_type_name` for more details). - pub fn push_const_name(&self, ct: &Const<'tcx>, output: &mut String, debug: bool) { - write!(output, "{}", ct).unwrap(); - output.push_str(": "); - self.push_type_name(ct.ty, output, debug); - } - - pub fn push_def_path(&self, def_id: DefId, output: &mut String) { - let def_path = self.tcx.def_path(def_id); - - // some_crate:: - if !(self.omit_local_crate_name && def_id.is_local()) { - output.push_str(&self.tcx.crate_name(def_path.krate).as_str()); - output.push_str("::"); - } - - // foo::bar::ItemName:: - for part in self.tcx.def_path(def_id).data { - if self.omit_disambiguators { - write!(output, "{}::", part.data.as_symbol()).unwrap(); - } else { - write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator).unwrap(); - } - } - - // remove final "::" - output.pop(); - output.pop(); - } - - fn push_generic_params<I>( - &self, - substs: SubstsRef<'tcx>, - projections: I, - output: &mut String, - debug: bool, - ) where - I: Iterator<Item = ty::PolyExistentialProjection<'tcx>>, - { - let mut projections = projections.peekable(); - if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() { - return; - } - - output.push('<'); - - for type_parameter in substs.types() { - self.push_type_name(type_parameter, output, debug); - output.push_str(", "); - } - - for projection in projections { - let projection = projection.skip_binder(); - let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str(); - output.push_str(name); - output.push_str("="); - self.push_type_name(projection.ty, output, debug); - output.push_str(", "); - } - - for const_parameter in substs.consts() { - self.push_const_name(const_parameter, output, debug); - output.push_str(", "); - } - - output.pop(); - output.pop(); - - output.push('>'); - } - - pub fn push_instance_as_string( - &self, - instance: Instance<'tcx>, - output: &mut String, - debug: bool, - ) { - self.push_def_path(instance.def_id(), output); - self.push_generic_params(instance.substs, iter::empty(), output, debug); - } -} diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml deleted file mode 100644 index 2693d29e41c..00000000000 --- a/src/librustc_mir/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_mir" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_mir" -path = "lib.rs" -doctest = false - -[dependencies] -either = "1.5.0" -rustc_graphviz = { path = "../librustc_graphviz" } -itertools = "0.8" -tracing = "0.1" -log_settings = "0.1.1" -polonius-engine = "0.12.0" -rustc_middle = { path = "../librustc_middle" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_index = { path = "../librustc_index" } -rustc_infer = { path = "../librustc_infer" } -rustc_lexer = { path = "../librustc_lexer" } -rustc_macros = { path = "../librustc_macros" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_session = { path = "../librustc_session" } -rustc_target = { path = "../librustc_target" } -rustc_trait_selection = { path = "../librustc_trait_selection" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -rustc_apfloat = { path = "../librustc_apfloat" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml deleted file mode 100644 index 97621f205fb..00000000000 --- a/src/librustc_mir_build/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_mir_build" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_mir_build" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_arena = { path = "../librustc_arena" } -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_apfloat = { path = "../librustc_apfloat" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_index = { path = "../librustc_index" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_infer = { path = "../librustc_infer" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rustc_target = { path = "../librustc_target" } -rustc_trait_selection = { path = "../librustc_trait_selection" } -rustc_ast = { path = "../librustc_ast" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml deleted file mode 100644 index 31d858849af..00000000000 --- a/src/librustc_parse/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_parse" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_parse" -path = "lib.rs" -doctest = false - -[dependencies] -bitflags = "1.0" -tracing = "0.1" -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_feature = { path = "../librustc_feature" } -rustc_lexer = { path = "../librustc_lexer" } -rustc_errors = { path = "../librustc_errors" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rustc_ast = { path = "../librustc_ast" } -unicode-normalization = "0.1.11" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_parse_format/Cargo.toml b/src/librustc_parse_format/Cargo.toml deleted file mode 100644 index 646509569f3..00000000000 --- a/src/librustc_parse_format/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_parse_format" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_parse_format" -path = "lib.rs" - -[dependencies] -rustc_span = { path = "../librustc_span" } -rustc_lexer = { path = "../librustc_lexer" } diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml deleted file mode 100644 index db481c0d0d4..00000000000 --- a/src/librustc_passes/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_passes" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_passes" -path = "lib.rs" - -[dependencies] -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_index = { path = "../librustc_index" } -rustc_session = { path = "../librustc_session" } -rustc_target = { path = "../librustc_target" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml deleted file mode 100644 index 38cfbd48de2..00000000000 --- a/src/librustc_plugin_impl/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_plugin_impl" -version = "0.0.0" -build = false -edition = "2018" - -[lib] -name = "rustc_plugin_impl" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_middle = { path = "../librustc_middle" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_lint = { path = "../librustc_lint" } -rustc_metadata = { path = "../librustc_metadata" } -rustc_ast = { path = "../librustc_ast" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml deleted file mode 100644 index 3641f0f8a31..00000000000 --- a/src/librustc_privacy/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_privacy" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_privacy" -path = "lib.rs" - -[dependencies] -rustc_middle = { path = "../librustc_middle" } -rustc_attr = { path = "../librustc_attr" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_typeck = { path = "../librustc_typeck" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rustc_data_structures = { path = "../librustc_data_structures" } -tracing = "0.1" diff --git a/src/librustc_query_system/Cargo.toml b/src/librustc_query_system/Cargo.toml deleted file mode 100644 index 1e89d379cb7..00000000000 --- a/src/librustc_query_system/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_query_system" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_query_system" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_arena = { path = "../librustc_arena" } -tracing = "0.1" -rustc-rayon-core = "0.3.0" -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_macros = { path = "../librustc_macros" } -rustc_index = { path = "../librustc_index" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_span = { path = "../librustc_span" } -parking_lot = "0.10" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml deleted file mode 100644 index e5260866f29..00000000000 --- a/src/librustc_resolve/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_resolve" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_resolve" -path = "lib.rs" -test = false -doctest = false - -[dependencies] -bitflags = "1.2.1" -tracing = "0.1" -rustc_ast = { path = "../librustc_ast" } -rustc_arena = { path = "../librustc_arena" } -rustc_middle = { path = "../librustc_middle" } -rustc_ast_lowering = { path = "../librustc_ast_lowering" } -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_expand = { path = "../librustc_expand" } -rustc_feature = { path = "../librustc_feature" } -rustc_hir = { path = "../librustc_hir" } -rustc_index = { path = "../librustc_index" } -rustc_metadata = { path = "../librustc_metadata" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml deleted file mode 100644 index 979a8da2a9f..00000000000 --- a/src/librustc_save_analysis/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_save_analysis" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_save_analysis" -path = "lib.rs" - -[dependencies] -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_ast = { path = "../librustc_ast" } -rustc_ast_pretty = { path = "../librustc_ast_pretty" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_hir = { path = "../librustc_hir" } -rustc_hir_pretty = { path = "../librustc_hir_pretty" } -rustc_lexer = { path = "../librustc_lexer" } -serde_json = "1" -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rls-data = "0.19" -rls-span = "0.5" diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml deleted file mode 100644 index 208bba1d962..00000000000 --- a/src/librustc_session/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_session" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_session" -path = "lib.rs" - -[dependencies] -bitflags = "1.2.1" -getopts = "0.2" -rustc_macros = { path = "../librustc_macros" } -tracing = "0.1" -rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } -rustc_target = { path = "../librustc_target" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_span = { path = "../librustc_span" } -rustc_fs_util = { path = "../librustc_fs_util" } -num_cpus = "1.0" -rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_span/Cargo.toml b/src/librustc_span/Cargo.toml deleted file mode 100644 index dd4928d4e32..00000000000 --- a/src/librustc_span/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_span" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_span" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_serialize = { path = "../librustc_serialize" } -rustc_macros = { path = "../librustc_macros" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_index = { path = "../librustc_index" } -rustc_arena = { path = "../librustc_arena" } -scoped-tls = "1.0" -unicode-width = "0.1.4" -cfg-if = "0.1.2" -tracing = "0.1" -sha-1 = "0.8" -md-5 = "0.8" diff --git a/src/librustc_symbol_mangling/Cargo.toml b/src/librustc_symbol_mangling/Cargo.toml deleted file mode 100644 index b44c0e4e027..00000000000 --- a/src/librustc_symbol_mangling/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_symbol_mangling" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_symbol_mangling" -path = "lib.rs" -doctest = false - -[dependencies] -tracing = "0.1" -punycode = "0.4.0" -rustc-demangle = "0.1.16" - -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -rustc_middle = { path = "../librustc_middle" } -rustc_hir = { path = "../librustc_hir" } -rustc_target = { path = "../librustc_target" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml deleted file mode 100644 index d2b50f44e43..00000000000 --- a/src/librustc_target/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_target" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_target" -path = "lib.rs" - -[dependencies] -bitflags = "1.2.1" -tracing = "0.1" -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_macros = { path = "../librustc_macros" } -rustc_serialize = { path = "../librustc_serialize" } -rustc_span = { path = "../librustc_span" } -rustc_index = { path = "../librustc_index" } diff --git a/src/librustc_trait_selection/Cargo.toml b/src/librustc_trait_selection/Cargo.toml deleted file mode 100644 index 444023baa69..00000000000 --- a/src/librustc_trait_selection/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_trait_selection" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_trait_selection" -path = "lib.rs" -doctest = false - -[dependencies] -rustc_parse_format = { path = "../librustc_parse_format" } -tracing = "0.1" -rustc_attr = { path = "../librustc_attr" } -rustc_middle = { path = "../librustc_middle" } -rustc_ast = { path = "../librustc_ast" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_index = { path = "../librustc_index" } -rustc_infer = { path = "../librustc_infer" } -rustc_macros = { path = "../librustc_macros" } -rustc_session = { path = "../librustc_session" } -rustc_span = { path = "../librustc_span" } -rustc_target = { path = "../librustc_target" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml deleted file mode 100644 index f5545f56293..00000000000 --- a/src/librustc_traits/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_traits" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_traits" -path = "lib.rs" - -[dependencies] -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_hir = { path = "../librustc_hir" } -rustc_index = { path = "../librustc_index" } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -chalk-ir = "0.14.0" -chalk-solve = "0.14.0" -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_infer = { path = "../librustc_infer" } -rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml deleted file mode 100644 index adc9740c2c1..00000000000 --- a/src/librustc_ty/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_ty" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_ty" -path = "lib.rs" - -[dependencies] -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_infer = { path = "../librustc_infer" } -rustc_span = { path = "../librustc_span" } -rustc_session = { path = "../librustc_session" } -rustc_target = { path = "../librustc_target" } -rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml deleted file mode 100644 index 82c6ac7a0cd..00000000000 --- a/src/librustc_typeck/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_typeck" -version = "0.0.0" -edition = "2018" - -[lib] -name = "rustc_typeck" -path = "lib.rs" -test = false -doctest = false - -[dependencies] -rustc_arena = { path = "../librustc_arena" } -tracing = "0.1" -rustc_middle = { path = "../librustc_middle" } -rustc_attr = { path = "../librustc_attr" } -rustc_data_structures = { path = "../librustc_data_structures" } -rustc_errors = { path = "../librustc_errors" } -rustc_hir = { path = "../librustc_hir" } -rustc_hir_pretty = { path = "../librustc_hir_pretty" } -rustc_target = { path = "../librustc_target" } -rustc_session = { path = "../librustc_session" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } -rustc_ast = { path = "../librustc_ast" } -rustc_span = { path = "../librustc_span" } -rustc_index = { path = "../librustc_index" } -rustc_infer = { path = "../librustc_infer" } -rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 09afb3cae5b..ede52394468 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -5,7 +5,6 @@ version = "0.0.0" edition = "2018" [lib] -name = "rustdoc" path = "lib.rs" [dependencies] @@ -19,4 +18,4 @@ tempfile = "3" itertools = "0.8" [dev-dependencies] -expect-test = "0.1" +expect-test = "1.0" diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 3d2785541be..484fbd0316d 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -75,8 +75,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { } }); debug!( - "get_blanket_impls: found applicable impl: {}\ - for trait_ref={:?}, ty={:?}", + "get_blanket_impls: found applicable impl: {} for trait_ref={:?}, ty={:?}", may_apply, trait_ref, ty ); if !may_apply { diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 96f0a1b7a7c..794a7bcaf1c 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -391,26 +391,25 @@ fn test_render_long_html() { (word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions")) .render_long_html(), "This is supported on <strong>Unix and Windows and debug-assertions enabled\ - </strong> only." + </strong> only." ); assert_eq!( (word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) .render_long_html(), "This is supported on <strong>Unix or Windows or debug-assertions enabled\ - </strong> only." + </strong> only." ); assert_eq!( (!(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions"))) .render_long_html(), "This is supported on <strong>neither Unix nor Windows nor debug-assertions \ - enabled</strong>." + enabled</strong>." ); assert_eq!( ((word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | (word_cfg("windows") & name_value_cfg("target_pointer_width", "64"))) .render_long_html(), - "This is supported on <strong>Unix and x86-64, or Windows and 64-bit</strong> \ - only." + "This is supported on <strong>Unix and x86-64, or Windows and 64-bit</strong> only." ); assert_eq!( (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(), @@ -420,7 +419,7 @@ fn test_render_long_html() { ((word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix")) .render_long_html(), "This is supported on <strong>(debug-assertions enabled or Windows) and Unix\ - </strong> only." + </strong> only." ); assert_eq!( name_value_cfg("target_feature", "sse2").render_long_html(), @@ -430,7 +429,7 @@ fn test_render_long_html() { (name_value_cfg("target_arch", "x86_64") & name_value_cfg("target_feature", "sse2")) .render_long_html(), "This is supported on <strong>x86-64 and target feature \ - <code>sse2</code></strong> only." + <code>sse2</code></strong> only." ); }) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 75fdcd5ec1c..8255bdab4f5 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -422,14 +422,13 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String { PatKind::Ref(ref p, _) => name_from_pat(&**p), PatKind::Lit(..) => { warn!( - "tried to get argument name from PatKind::Lit, \ - which is silly in function arguments" + "tried to get argument name from PatKind::Lit, which is silly in function arguments" ); "()".to_string() } PatKind::Range(..) => panic!( "tried to get argument name from PatKind::Range, \ - which is not allowed in function arguments" + which is not allowed in function arguments" ), PatKind::Slice(ref begin, ref mid, ref end) => { let begin = begin.iter().map(|p| name_from_pat(&**p)); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 14df4e7aa8e..a5fc0757816 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -416,14 +416,12 @@ impl Options { return Err(1); } else if !ret.is_empty() { diag.struct_warn(&format!( - "theme file \"{}\" is missing CSS rules from the \ - default theme", + "theme file \"{}\" is missing CSS rules from the default theme", theme_s )) .warn("the theme may appear incorrect when loaded") .help(&format!( - "to see what rules are missing, call `rustdoc \ - --check-theme \"{}\"`", + "to see what rules are missing, call `rustdoc --check-theme \"{}\"`", theme_s )) .emit(); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 7c89b38a92c..074a43f2a70 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -561,8 +561,7 @@ fn run_global_ctxt( if let Some(ref m) = krate.module { if let None | Some("") = m.doc_value() { let help = "The following guide may be of use:\n\ - https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation\ - .html"; + https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html"; tcx.struct_lint_node( rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS, ctxt.as_local_hir_id(m.def_id).unwrap(), @@ -581,7 +580,7 @@ fn run_global_ctxt( .struct_warn(&format!("the `#![doc({})]` attribute is considered deprecated", name)); msg.warn( "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \ - for more information", + for more information", ); if name == "no_default_passes" { @@ -614,7 +613,7 @@ fn run_global_ctxt( report_deprecated_attr("plugins = \"...\"", diag); eprintln!( "WARNING: `#![doc(plugins = \"...\")]` \ - no longer functions; see CVE-2018-1000622" + no longer functions; see CVE-2018-1000622" ); continue; } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 699f8c36cba..2da9c68b196 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -833,7 +833,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> write!( f, "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \ - title=\"type {path}::{name}\">{name}</a>", + title=\"type {path}::{name}\">{name}</a>", url = url, shortty = ItemType::AssocType, name = name, diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 26557fc1cb7..4769edc50ff 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -27,7 +27,7 @@ pub fn render_with_highlighting( write!( out, "<div class='information'><div class='tooltip {}'>ⓘ<span \ - class='tooltiptext'>{}</span></div></div>", + class='tooltiptext'>{}</span></div></div>", class, tooltip ) .unwrap(); diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index 398cd4f670e..c79471b1fae 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -9,7 +9,7 @@ fn test_html_highlighting() { write_code(&mut out, src); format!("{}<pre><code>{}</code></pre>\n", STYLE, out) }; - expect_file!["src/librustdoc/html/highlight/fixtures/sample.html"].assert_eq(&html); + expect_file!["fixtures/sample.html"].assert_eq(&html); } const STYLE: &str = r#" diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index fd67a66395d..287c85b8c22 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -210,8 +210,8 @@ pub fn render<T: Print, S: Print>( .collect::<String>(), filter_crates = if layout.generate_search_filter { "<select id=\"crate-search\">\ - <option value=\"All crates\">All crates</option>\ - </select>" + <option value=\"All crates\">All crates</option>\ + </select>" } else { "" }, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 894d868dcc6..098ece9a1d5 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -519,8 +519,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> { Some(Event::FootnoteReference(ref reference)) => { let entry = self.get_entry(&reference); let reference = format!( - "<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}\ - </a></sup>", + "<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>", (*entry).1 ); return Some(Event::Html(reference.into())); diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index f071f3d5b4e..8e618733f07 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -140,25 +140,26 @@ fn test_header() { t( "# Foo bar", - "<h1 id=\"foo-bar\" class=\"section-header\">\ - <a href=\"#foo-bar\">Foo bar</a></h1>", + "<h1 id=\"foo-bar\" class=\"section-header\"><a href=\"#foo-bar\">Foo bar</a></h1>", ); t( "## Foo-bar_baz qux", - "<h2 id=\"foo-bar_baz-qux\" class=\"section-\ - header\"><a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h2>", + "<h2 id=\"foo-bar_baz-qux\" class=\"section-header\">\ + <a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h2>", ); t( "### **Foo** *bar* baz!?!& -_qux_-%", "<h3 id=\"foo-bar-baz--qux-\" class=\"section-header\">\ - <a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \ - <em>bar</em> baz!?!& -<em>qux</em>-%</a></h3>", + <a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \ + <em>bar</em> baz!?!& -<em>qux</em>-%</a>\ + </h3>", ); t( "#### **Foo?** & \\*bar?!* _`baz`_ ❤ #qux", "<h4 id=\"foo--bar--baz--qux\" class=\"section-header\">\ - <a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> & *bar?!* \ - <em><code>baz</code></em> ❤ #qux</a></h4>", + <a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> & *bar?!* \ + <em><code>baz</code></em> ❤ #qux</a>\ + </h4>", ); } @@ -174,38 +175,32 @@ fn test_header_ids_multiple_blocks() { t( &mut map, "# Example", - "<h1 id=\"example\" class=\"section-header\">\ - <a href=\"#example\">Example</a></h1>", + "<h1 id=\"example\" class=\"section-header\"><a href=\"#example\">Example</a></h1>", ); t( &mut map, "# Panics", - "<h1 id=\"panics\" class=\"section-header\">\ - <a href=\"#panics\">Panics</a></h1>", + "<h1 id=\"panics\" class=\"section-header\"><a href=\"#panics\">Panics</a></h1>", ); t( &mut map, "# Example", - "<h1 id=\"example-1\" class=\"section-header\">\ - <a href=\"#example-1\">Example</a></h1>", + "<h1 id=\"example-1\" class=\"section-header\"><a href=\"#example-1\">Example</a></h1>", ); t( &mut map, "# Main", - "<h1 id=\"main-1\" class=\"section-header\">\ - <a href=\"#main-1\">Main</a></h1>", + "<h1 id=\"main-1\" class=\"section-header\"><a href=\"#main-1\">Main</a></h1>", ); t( &mut map, "# Example", - "<h1 id=\"example-2\" class=\"section-header\">\ - <a href=\"#example-2\">Example</a></h1>", + "<h1 id=\"example-2\" class=\"section-header\"><a href=\"#example-2\">Example</a></h1>", ); t( &mut map, "# Panics", - "<h1 id=\"panics-1\" class=\"section-header\">\ - <a href=\"#panics-1\">Panics</a></h1>", + "<h1 id=\"panics-1\" class=\"section-header\"><a href=\"#panics-1\">Panics</a></h1>", ); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 90206d27781..57b3b9502a3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1061,13 +1061,14 @@ themePicker.onblur = handleThemeButtonsBlur; let content = format!( "<h1 class='fqn'>\ - <span class='in-band'>List of all crates</span>\ -</h1><ul class='mod'>{}</ul>", + <span class='in-band'>List of all crates</span>\ + </h1>\ + <ul class='crate mod'>{}</ul>", krates .iter() .map(|s| { format!( - "<li><a class=\"mod\" href=\"{}index.html\">{}</a></li>", + "<li><a class=\"crate mod\" href=\"{}index.html\">{}</a></li>", ensure_trailing_slash(s), s ) @@ -1311,15 +1312,16 @@ impl AllTypes { write!( f, "<h1 class='fqn'>\ - <span class='out-of-band'>\ - <span id='render-detail'>\ - <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\ - [<span class='inner'>−</span>]\ - </a>\ - </span> - </span> - <span class='in-band'>List of all items</span>\ - </h1>" + <span class='out-of-band'>\ + <span id='render-detail'>\ + <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \ + title=\"collapse all docs\">\ + [<span class='inner'>−</span>]\ + </a>\ + </span> + </span> + <span class='in-band'>List of all items</span>\ + </h1>" ); print_entries(f, &self.structs, "Structs", "structs"); print_entries(f, &self.enums, "Enums", "enums"); @@ -1349,20 +1351,20 @@ impl Setting { match *self { Setting::Section { ref description, ref sub_settings } => format!( "<div class='setting-line'>\ - <div class='title'>{}</div>\ - <div class='sub-settings'>{}</div> - </div>", + <div class='title'>{}</div>\ + <div class='sub-settings'>{}</div> + </div>", description, sub_settings.iter().map(|s| s.display()).collect::<String>() ), Setting::Entry { ref js_data_name, ref description, ref default_value } => format!( "<div class='setting-line'>\ - <label class='toggle'>\ - <input type='checkbox' id='{}' {}>\ - <span class='slider'></span>\ - </label>\ - <div>{}</div>\ - </div>", + <label class='toggle'>\ + <input type='checkbox' id='{}' {}>\ + <span class='slider'></span>\ + </label>\ + <div>{}</div>\ + </div>", js_data_name, if *default_value { " checked" } else { "" }, description, @@ -1880,30 +1882,29 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) { write!( w, "Non-exhaustive structs could have additional fields added in future. \ - Therefore, non-exhaustive structs cannot be constructed in external crates \ - using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \ - matched against without a wildcard <code>..</code>; and \ - struct update syntax will not work." + Therefore, non-exhaustive structs cannot be constructed in external crates \ + using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \ + matched against without a wildcard <code>..</code>; and \ + struct update syntax will not work." ); } else if item.is_enum() { write!( w, "Non-exhaustive enums could have additional variants added in future. \ - Therefore, when matching against variants of non-exhaustive enums, an \ - extra wildcard arm must be added to account for any future variants." + Therefore, when matching against variants of non-exhaustive enums, an \ + extra wildcard arm must be added to account for any future variants." ); } else if item.is_variant() { write!( w, "Non-exhaustive enum variants could have additional fields added in future. \ - Therefore, non-exhaustive enum variants cannot be constructed in external \ - crates and cannot be matched against." + Therefore, non-exhaustive enum variants cannot be constructed in external \ + crates and cannot be matched against." ); } else { write!( w, - "This type will require a wildcard arm in any match statements or \ - constructors." + "This type will require a wildcard arm in any match statements or constructors." ); } @@ -2100,12 +2101,11 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: let doc_value = myitem.doc_value().unwrap_or(""); write!( w, - "\ - <tr class='{stab}{add}module-item'>\ - <td><a class=\"{class}\" href=\"{href}\" \ - title='{title}'>{name}</a>{unsafety_flag}</td>\ - <td class='docblock-short'>{stab_tags}{docs}</td>\ - </tr>", + "<tr class='{stab}{add}module-item'>\ + <td><a class=\"{class}\" href=\"{href}\" \ + title='{title}'>{name}</a>{unsafety_flag}</td>\ + <td class='docblock-short'>{stab_tags}{docs}</td>\ + </tr>", name = *myitem.name.as_ref().unwrap(), stab_tags = stability_tags(myitem), docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(), @@ -2254,8 +2254,7 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons write!( w, - "{vis}const \ - {name}: {typ}", + "{vis}const {name}: {typ}", vis = it.visibility.print_with_space(), name = it.name.as_ref().unwrap(), typ = c.type_.print(), @@ -2289,8 +2288,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static render_attributes(w, it, false); write!( w, - "{vis}static {mutability}\ - {name}: {typ}</pre>", + "{vis}static {mutability} {name}: {typ}</pre>", vis = it.visibility.print_with_space(), mutability = s.mutability.print_with_space(), name = it.name.as_ref().unwrap(), @@ -2316,7 +2314,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func write!( w, "{vis}{constness}{asyncness}{unsafety}{abi}fn \ - {name}{generics}{decl}{spotlight}{where_clause}</pre>", + {name}{generics}{decl}{spotlight}{where_clause}</pre>", vis = it.visibility.print_with_space(), constness = f.header.constness.print_with_space(), asyncness = f.header.asyncness.print_with_space(), @@ -2507,10 +2505,9 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) { write!( w, - " - <h2 id='{0}' class='small-section-header'>\ - {1}<a href='#{0}' class='anchor'></a>\ - </h2>{2}", + "<h2 id='{0}' class='small-section-header'>\ + {1}<a href='#{0}' class='anchor'></a>\ + </h2>{2}", id, title, extra_content ) } @@ -2839,7 +2836,7 @@ fn render_assoc_item( write!( w, "{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\ - {generics}{decl}{spotlight}{where_clause}", + {generics}{decl}{spotlight}{where_clause}", if parent == ItemType::Trait { " " } else { "" }, meth.visibility.print_with_space(), header.constness.print_with_space(), @@ -2914,9 +2911,9 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct write!( w, "<span id=\"{id}\" class=\"{item_type} small-section-header\">\ - <a href=\"#{id}\" class=\"anchor field\"></a>\ - <code>{name}: {ty}</code>\ - </span>", + <a href=\"#{id}\" class=\"anchor field\"></a>\ + <code>{name}: {ty}</code>\ + </span>", item_type = ItemType::StructField, id = id, name = field.name.as_ref().unwrap(), @@ -2958,9 +2955,9 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, write!( w, "<span id=\"{id}\" class=\"{shortty} small-section-header\">\ - <a href=\"#{id}\" class=\"anchor field\"></a>\ - <code>{name}: {ty}</code>\ - </span>", + <a href=\"#{id}\" class=\"anchor field\"></a>\ + <code>{name}: {ty}</code>\ + </span>", id = id, name = name, shortty = ItemType::StructField, @@ -3085,9 +3082,9 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca write!( w, "<span id=\"{id}\" class=\"variant small-section-header\">\ - <a href=\"#{id}\" class=\"anchor field\"></a>\ - <code>{f}: {t}\ - </code></span>", + <a href=\"#{id}\" class=\"anchor field\"></a>\ + <code>{f}: {t}</code>\ + </span>", id = id, f = field.name.as_ref().unwrap(), t = ty.print() @@ -3300,23 +3297,19 @@ fn render_assoc_items( AssocItemRender::All => { write!( w, - "\ - <h2 id='implementations' class='small-section-header'>\ - Implementations<a href='#implementations' class='anchor'></a>\ - </h2>\ - " + "<h2 id='implementations' class='small-section-header'>\ + Implementations<a href='#implementations' class='anchor'></a>\ + </h2>" ); RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { write!( w, - "\ - <h2 id='deref-methods' class='small-section-header'>\ - Methods from {}<Target = {}>\ - <a href='#deref-methods' class='anchor'></a>\ - </h2>\ - ", + "<h2 id='deref-methods' class='small-section-header'>\ + Methods from {}<Target = {}>\ + <a href='#deref-methods' class='anchor'></a>\ + </h2>", trait_.print(), type_.print() ); @@ -3363,11 +3356,10 @@ fn render_assoc_items( if !impls.is_empty() { write!( w, - "\ - <h2 id='trait-implementations' class='small-section-header'>\ - Trait Implementations<a href='#trait-implementations' class='anchor'></a>\ - </h2>\ - <div id='trait-implementations-list'>{}</div>", + "<h2 id='trait-implementations' class='small-section-header'>\ + Trait Implementations<a href='#trait-implementations' class='anchor'></a>\ + </h2>\ + <div id='trait-implementations-list'>{}</div>", impls ); } @@ -3375,13 +3367,11 @@ fn render_assoc_items( if !synthetic.is_empty() { write!( w, - "\ - <h2 id='synthetic-implementations' class='small-section-header'>\ - Auto Trait Implementations\ - <a href='#synthetic-implementations' class='anchor'></a>\ - </h2>\ - <div id='synthetic-implementations-list'>\ - " + "<h2 id='synthetic-implementations' class='small-section-header'>\ + Auto Trait Implementations\ + <a href='#synthetic-implementations' class='anchor'></a>\ + </h2>\ + <div id='synthetic-implementations-list'>" ); render_impls(cx, w, &synthetic, containing_item, cache); write!(w, "</div>"); @@ -3390,13 +3380,11 @@ fn render_assoc_items( if !blanket_impl.is_empty() { write!( w, - "\ - <h2 id='blanket-implementations' class='small-section-header'>\ - Blanket Implementations\ - <a href='#blanket-implementations' class='anchor'></a>\ - </h2>\ - <div id='blanket-implementations-list'>\ - " + "<h2 id='blanket-implementations' class='small-section-header'>\ + Blanket Implementations\ + <a href='#blanket-implementations' class='anchor'></a>\ + </h2>\ + <div id='blanket-implementations-list'>" ); render_impls(cx, w, &blanket_impl, containing_item, cache); write!(w, "</div>"); @@ -3477,7 +3465,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { if out.is_empty() { out.push_str(&format!( "<h3 class=\"notable\">Notable traits for {}</h3>\ - <code class=\"content\">", + <code class=\"content\">", impl_.for_.print() )); trait_.push_str(&impl_.for_.print().to_string()); @@ -3913,8 +3901,8 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca write!( buffer, "<div class='block version'>\ - <p>Version {}</p>\ - </div>", + <p>Version {}</p>\ + </div>", Escape(version) ); } @@ -4189,7 +4177,7 @@ fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) { if let doctree::Plain = s.struct_type { sidebar.push_str(&format!( "<a class=\"sidebar-title\" href=\"#fields\">Fields</a>\ - <div class=\"sidebar-links\">{}</div>", + <div class=\"sidebar-links\">{}</div>", fields )); } @@ -4316,8 +4304,8 @@ fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) { res.sort(); sidebar.push_str(&format!( "<a class=\"sidebar-title\" href=\"#foreign-impls\">\ - Implementations on Foreign Types</a><div \ - class=\"sidebar-links\">{}</div>", + Implementations on Foreign Types</a>\ + <div class=\"sidebar-links\">{}</div>", res.into_iter() .map(|(name, id)| format!("<a href=\"#{}\">{}</a>", id, Escape(&name))) .collect::<Vec<_>>() diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index aaa73b100c2..02a7362bb3b 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -52,7 +52,7 @@ impl<'a> DocFolder for SourceCollector<'a> { Err(e) => { println!( "warning: source code was requested to be rendered, \ - but processing `{}` had an error: {}", + but processing `{}` had an error: {}", item.source.filename, e ); println!(" skipping rendering of source code"); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index a1eef5c1202..1b3eb2011af 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2740,10 +2740,17 @@ function defocusSearchBar() { }); } + function enableSearchInput() { + if (search_input) { + search_input.removeAttribute('disabled'); + } + } + window.addSearchOptions = function(crates) { var elem = document.getElementById("crate-search"); if (!elem) { + enableSearchInput(); return; } var crates_text = []; @@ -2781,10 +2788,7 @@ function defocusSearchBar() { elem.value = savedCrate; } } - - if (search_input) { - search_input.removeAttribute('disabled'); - } + enableSearchInput(); }; function buildHelperPopup() { diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index f910bfffc22..b4571018270 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -178,6 +178,9 @@ pre { .content span.externcrate, .content span.mod, .content a.mod { color: #acccf9; } +.content ul.crate a.crate { + font: 16px/1.6 "Fira Sans"; +} .content span.struct, .content a.struct { color: #ffa0a5; } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 8658b39b455..73a783d5406 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -153,7 +153,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "passes", "list of passes to also run, you might want to pass it multiple times; a value of \ - `list` will print available passes", + `list` will print available passes", "PASSES", ) }), @@ -183,7 +183,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "html-in-header", "files to include inline in the <head> section of a rendered Markdown file \ - or generated documentation", + or generated documentation", "FILES", ) }), @@ -192,7 +192,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "html-before-content", "files to include inline between <body> and the content of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -201,7 +201,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "html-after-content", "files to include inline between the content and </body> of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -210,7 +210,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "markdown-before-content", "files to include inline between <body> and the content of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -219,7 +219,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "markdown-after-content", "files to include inline between the content and </body> of a rendered \ - Markdown file or generated documentation", + Markdown file or generated documentation", "FILES", ) }), @@ -234,8 +234,8 @@ fn opts() -> Vec<RustcOptGroup> { "e", "extend-css", "To add some CSS rules with a given file to generate doc with your \ - own theme. However, your theme might break if the rustdoc's generated HTML \ - changes, so be careful!", + own theme. However, your theme might break if the rustdoc's generated HTML \ + changes, so be careful!", "PATH", ) }), @@ -248,7 +248,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "playground-url", "URL to send code snippets to, may be reset by --markdown-playground-url \ - or `#![doc(html_playground_url=...)]`", + or `#![doc(html_playground_url=...)]`", "URL", ) }), @@ -281,7 +281,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "resource-suffix", "suffix to add to CSS and JavaScript files, e.g., \"light.css\" will become \ - \"light-suffix.css\"", + \"light-suffix.css\"", "PATH", ) }), @@ -343,7 +343,7 @@ fn opts() -> Vec<RustcOptGroup> { "", "static-root-path", "Path string to force loading static files from in output pages. \ - If not set, uses combinations of '../' to reach the documentation root.", + If not set, uses combinations of '../' to reach the documentation root.", "PATH", ) }), diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index d1f2c12ccd6..beb1f13ca6f 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -1,7 +1,6 @@ -use rustc_ast::token; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler}; -use rustc_parse::lexer::StringReader as Lexer; +use rustc_parse::parse_stream_from_source_str; use rustc_session::parse::ParseSess; use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileName, InnerSpan}; @@ -28,49 +27,34 @@ struct SyntaxChecker<'a, 'tcx> { impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) { - let buffered_messages = Lrc::new(Lock::new(vec![])); - - let emitter = BufferEmitter { messages: Lrc::clone(&buffered_messages) }; + let buffer = Lrc::new(Lock::new(Buffer::default())); + let emitter = BufferEmitter { buffer: Lrc::clone(&buffer) }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let handler = Handler::with_emitter(false, None, Box::new(emitter)); + let source = dox[code_block.code].to_owned(); let sess = ParseSess::with_span_handler(handler, sm); - let source_file = sess.source_map().new_source_file( - FileName::Custom(String::from("doctest")), - dox[code_block.code].to_owned(), - ); - - let validation_status = rustc_driver::catch_fatal_errors(|| { - let mut has_syntax_errors = false; - let mut only_whitespace = true; - // even if there is a syntax error, we need to run the lexer over the whole file - let mut lexer = Lexer::new(&sess, source_file, None); - loop { - match lexer.next_token().kind { - token::Eof => break, - token::Whitespace => (), - token::Unknown(..) => has_syntax_errors = true, - _ => only_whitespace = false, - } - } - if has_syntax_errors { - Some(CodeBlockInvalid::SyntaxError) - } else if only_whitespace { - Some(CodeBlockInvalid::Empty) - } else { - None - } + let is_empty = rustc_driver::catch_fatal_errors(|| { + parse_stream_from_source_str( + FileName::Custom(String::from("doctest")), + source, + &sess, + None, + ) + .is_empty() }) - .unwrap_or(Some(CodeBlockInvalid::SyntaxError)); + .unwrap_or(false); + let buffer = buffer.borrow(); - if let Some(code_block_invalid) = validation_status { + if buffer.has_errors || is_empty { let mut diag = if let Some(sp) = super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs) { - let warning_message = match code_block_invalid { - CodeBlockInvalid::SyntaxError => "could not parse code block as Rust code", - CodeBlockInvalid::Empty => "Rust code block is empty", + let warning_message = if buffer.has_errors { + "could not parse code block as Rust code" + } else { + "Rust code block is empty" }; let mut diag = self.cx.sess().struct_span_warn(sp, warning_message); @@ -102,7 +86,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { }; // FIXME(#67563): Provide more context for these errors by displaying the spans inline. - for message in buffered_messages.borrow().iter() { + for message in buffer.messages.iter() { diag.note(&message); } @@ -125,21 +109,26 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> { } } +#[derive(Default)] +struct Buffer { + messages: Vec<String>, + has_errors: bool, +} + struct BufferEmitter { - messages: Lrc<Lock<Vec<String>>>, + buffer: Lrc<Lock<Buffer>>, } impl Emitter for BufferEmitter { fn emit_diagnostic(&mut self, diag: &Diagnostic) { - self.messages.borrow_mut().push(format!("error from rustc: {}", diag.message[0].0)); + let mut buffer = self.buffer.borrow_mut(); + buffer.messages.push(format!("error from rustc: {}", diag.message[0].0)); + if diag.is_error() { + buffer.has_errors = true; + } } fn source_map(&self) -> Option<&Lrc<SourceMap>> { None } } - -enum CodeBlockInvalid { - SyntaxError, - Empty, -} diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8d4eb67204f..f497f341e11 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1157,7 +1157,7 @@ fn report_diagnostic( // Print the line containing the `link_range` and manually mark it with '^'s. diag.note(&format!( "the link appears in this line:\n\n{line}\n\ - {indicator: <before$}{indicator:^<found$}", + {indicator: <before$}{indicator:^<found$}", line = line, indicator = "", before = link_range.start - last_new_line_offset, diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 0eebdbd87ed..75a65966667 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -284,8 +284,7 @@ impl<'a> DocFolder for ImplStripper<'a> { if let Some(did) = typaram.def_id() { if did.is_local() && !self.retained.contains(&did) { debug!( - "ImplStripper: stripped item in trait's generics; \ - removing impl" + "ImplStripper: stripped item in trait's generics; removing impl" ); return None; } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index f244956e503..9173d8e9605 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -9,7 +9,7 @@ pub const STRIP_PRIVATE: Pass = Pass { name: "strip-private", run: strip_private, description: "strips all private items from a crate which cannot be seen externally, \ - implies strip-priv-imports", + implies strip-priv-imports", }; /// Strip private items from the point of view of a crate or externally from a diff --git a/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs b/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs index e1991046d43..7289ceee95b 100644 --- a/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs +++ b/src/test/codegen-units/item-collection/cross-crate-generic-functions.rs @@ -6,15 +6,15 @@ // aux-build:cgu_generic_function.rs extern crate cgu_generic_function; -//~ MONO_ITEM fn cross_crate_generic_functions::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn cgu_generic_function::bar[0]<u32> - //~ MONO_ITEM fn cgu_generic_function::foo[0]<u32> + //~ MONO_ITEM fn cgu_generic_function::bar::<u32> + //~ MONO_ITEM fn cgu_generic_function::foo::<u32> let _ = cgu_generic_function::foo(1u32); - //~ MONO_ITEM fn cgu_generic_function::bar[0]<u64> - //~ MONO_ITEM fn cgu_generic_function::foo[0]<u64> + //~ MONO_ITEM fn cgu_generic_function::bar::<u64> + //~ MONO_ITEM fn cgu_generic_function::foo::<u64> let _ = cgu_generic_function::foo(2u64); // This should not introduce a codegen item diff --git a/src/test/codegen-units/item-collection/cross-crate-trait-method.rs b/src/test/codegen-units/item-collection/cross-crate-trait-method.rs index 442438b64b6..dc0984c8a98 100644 --- a/src/test/codegen-units/item-collection/cross-crate-trait-method.rs +++ b/src/test/codegen-units/item-collection/cross-crate-trait-method.rs @@ -8,7 +8,7 @@ extern crate cgu_export_trait_method; use cgu_export_trait_method::Trait; -//~ MONO_ITEM fn cross_crate_trait_method::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { // The object code of these methods is contained in the external crate, so @@ -19,31 +19,31 @@ fn start(_: isize, _: *const *const u8) -> isize { // Currently, no object code is generated for trait methods with default // implementations, unless they are actually called from somewhere. Therefore // we cannot import the implementations and have to create our own inline. - //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl[0]<u32> + //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl let _ = Trait::with_default_impl(0u32); - //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl[0]<char> + //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl let _ = Trait::with_default_impl('c'); - //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<u32, &str> + //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<&str> let _ = Trait::with_default_impl_generic(0u32, "abc"); - //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<u32, bool> + //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<bool> let _ = Trait::with_default_impl_generic(0u32, false); - //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<char, i16> + //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i16> let _ = Trait::with_default_impl_generic('x', 1i16); - //~ MONO_ITEM fn cgu_export_trait_method::Trait[0]::with_default_impl_generic[0]<char, i32> + //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i32> let _ = Trait::with_default_impl_generic('y', 0i32); - //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[1]::without_default_impl_generic[0]<char> + //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<char> let _: (u32, char) = Trait::without_default_impl_generic('c'); - //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[1]::without_default_impl_generic[0]<bool> + //~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool> let _: (u32, bool) = Trait::without_default_impl_generic(false); - //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[0]::without_default_impl_generic[0]<char> + //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<char> let _: (char, char) = Trait::without_default_impl_generic('c'); - //~ MONO_ITEM fn cgu_export_trait_method::{{impl}}[0]::without_default_impl_generic[0]<bool> + //~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool> let _: (char, bool) = Trait::without_default_impl_generic(false); 0 diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs index 27fb3cb1380..adde5745feb 100644 --- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -4,19 +4,19 @@ #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDtor> - shim(Some(StructWithDtor)) @@ drop_in_place_intrinsic-cgu.0[Internal] struct StructWithDtor(u32); impl Drop for StructWithDtor { - //~ MONO_ITEM fn drop_in_place_intrinsic::{{impl}}[0]::drop[0] + //~ MONO_ITEM fn <StructWithDtor as std::ops::Drop>::drop fn drop(&mut self) {} } -//~ MONO_ITEM fn drop_in_place_intrinsic::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<[StructWithDtor; 2]> - shim(Some([StructWithDtor; 2])) @@ drop_in_place_intrinsic-cgu.0[Internal] let x = [StructWithDtor(0), StructWithDtor(1)]; drop_slice_in_place(&x); @@ -24,13 +24,13 @@ fn start(_: isize, _: *const *const u8) -> isize { 0 } -//~ MONO_ITEM fn drop_in_place_intrinsic::drop_slice_in_place[0] +//~ MONO_ITEM fn drop_slice_in_place fn drop_slice_in_place(x: &[StructWithDtor]) { unsafe { // This is the interesting thing in this test case: Normally we would // not have drop-glue for the unsized [StructWithDtor]. This has to be // generated though when the drop_in_place() intrinsic is used. - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal] - ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]); + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<[StructWithDtor]> - shim(Some([StructWithDtor])) @@ drop_in_place_intrinsic-cgu.0[Internal] + ::std::intrinsics::drop_in_place(x as *const _ as *mut [StructWithDtor]); } } diff --git a/src/test/codegen-units/item-collection/function-as-argument.rs b/src/test/codegen-units/item-collection/function-as-argument.rs index 3f61f124d24..2329dec385f 100644 --- a/src/test/codegen-units/item-collection/function-as-argument.rs +++ b/src/test/codegen-units/item-collection/function-as-argument.rs @@ -1,3 +1,4 @@ +// ignore-tidy-linelength // compile-flags:-Zprint-mono-items=eager #![deny(dead_code)] @@ -13,26 +14,26 @@ fn take_fn_pointer<T1, T2>(f: fn(T1, T2), x: T1, y: T2) { (f)(x, y) } -//~ MONO_ITEM fn function_as_argument::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn function_as_argument::take_fn_once[0]<u32, &str, fn(u32, &str)> - //~ MONO_ITEM fn function_as_argument::function[0]<u32, &str> - //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(u32, &str), (u32, &str)> + //~ MONO_ITEM fn take_fn_once::<u32, &str, fn(u32, &str) {function::<u32, &str>}> + //~ MONO_ITEM fn function::<u32, &str> + //~ MONO_ITEM fn <fn(u32, &str) {function::<u32, &str>} as std::ops::FnOnce<(u32, &str)>>::call_once - shim(fn(u32, &str) {function::<u32, &str>}) take_fn_once(function, 0u32, "abc"); - //~ MONO_ITEM fn function_as_argument::take_fn_once[0]<char, f64, fn(char, f64)> - //~ MONO_ITEM fn function_as_argument::function[0]<char, f64> - //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(char, f64), (char, f64)> + //~ MONO_ITEM fn take_fn_once::<char, f64, fn(char, f64) {function::<char, f64>}> + //~ MONO_ITEM fn function::<char, f64> + //~ MONO_ITEM fn <fn(char, f64) {function::<char, f64>} as std::ops::FnOnce<(char, f64)>>::call_once - shim(fn(char, f64) {function::<char, f64>}) take_fn_once(function, 'c', 0f64); - //~ MONO_ITEM fn function_as_argument::take_fn_pointer[0]<i32, ()> - //~ MONO_ITEM fn function_as_argument::function[0]<i32, ()> + //~ MONO_ITEM fn take_fn_pointer::<i32, ()> + //~ MONO_ITEM fn function::<i32, ()> take_fn_pointer(function, 0i32, ()); - //~ MONO_ITEM fn function_as_argument::take_fn_pointer[0]<f32, i64> - //~ MONO_ITEM fn function_as_argument::function[0]<f32, i64> + //~ MONO_ITEM fn take_fn_pointer::<f32, i64> + //~ MONO_ITEM fn function::<f32, i64> take_fn_pointer(function, 0f32, 0i64); 0 diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs index 675bdfdb4d2..45e4a0d6d76 100644 --- a/src/test/codegen-units/item-collection/generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs @@ -37,22 +37,22 @@ enum EnumNoDrop<T1, T2> { struct NonGenericNoDrop(i32); struct NonGenericWithDrop(i32); -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal] impl Drop for NonGenericWithDrop { - //~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0] + //~ MONO_ITEM fn <NonGenericWithDrop as std::ops::Drop>::drop fn drop(&mut self) {} } -//~ MONO_ITEM fn generic_drop_glue::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDrop<i8, char>> - shim(Some(StructWithDrop<i8, char>)) @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn <StructWithDrop<i8, char> as std::ops::Drop>::drop let _ = StructWithDrop { x: 0i8, y: 'a' }.x; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDrop<&str, NonGenericNoDrop>> - shim(Some(StructWithDrop<&str, NonGenericNoDrop>)) @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn <StructWithDrop<&str, NonGenericNoDrop> as std::ops::Drop>::drop let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y; // Should produce no drop glue @@ -60,18 +60,18 @@ fn start(_: isize, _: *const *const u8) -> isize { // This is supposed to generate drop-glue because it contains a field that // needs to be dropped. - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructNoDrop<NonGenericWithDrop, f64>> - shim(Some(StructNoDrop<NonGenericWithDrop, f64>)) @@ generic_drop_glue-cgu.0[Internal] let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<EnumWithDrop<i32, i64>> - shim(Some(EnumWithDrop<i32, i64>)) @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn <EnumWithDrop<i32, i64> as std::ops::Drop>::drop let _ = match EnumWithDrop::A::<i32, i64>(0) { EnumWithDrop::A(x) => x, EnumWithDrop::B(x) => x as i32 }; - //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<EnumWithDrop<f64, f32>> - shim(Some(EnumWithDrop<f64, f32>)) @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn <EnumWithDrop<f64, f32> as std::ops::Drop>::drop let _ = match EnumWithDrop::B::<f64, f32>(1.0) { EnumWithDrop::A(x) => x, EnumWithDrop::B(x) => x as f64 diff --git a/src/test/codegen-units/item-collection/generic-functions.rs b/src/test/codegen-units/item-collection/generic-functions.rs index 83909704204..04383bb8edb 100644 --- a/src/test/codegen-units/item-collection/generic-functions.rs +++ b/src/test/codegen-units/item-collection/generic-functions.rs @@ -16,39 +16,39 @@ fn foo3<T1, T2, T3>(a: T1, b: T2, c: T3) -> (T1, T2, T3) { } // This function should be instantiated even if no used -//~ MONO_ITEM fn generic_functions::lifetime_only[0] +//~ MONO_ITEM fn lifetime_only pub fn lifetime_only<'a>(a: &'a u32) -> &'a u32 { a } -//~ MONO_ITEM fn generic_functions::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn generic_functions::foo1[0]<i32> + //~ MONO_ITEM fn foo1::<i32> let _ = foo1(2i32); - //~ MONO_ITEM fn generic_functions::foo1[0]<i64> + //~ MONO_ITEM fn foo1::<i64> let _ = foo1(2i64); - //~ MONO_ITEM fn generic_functions::foo1[0]<&str> + //~ MONO_ITEM fn foo1::<&str> let _ = foo1("abc"); - //~ MONO_ITEM fn generic_functions::foo1[0]<char> + //~ MONO_ITEM fn foo1::<char> let _ = foo1('v'); - //~ MONO_ITEM fn generic_functions::foo2[0]<i32, i32> + //~ MONO_ITEM fn foo2::<i32, i32> let _ = foo2(2i32, 2i32); - //~ MONO_ITEM fn generic_functions::foo2[0]<i64, &str> + //~ MONO_ITEM fn foo2::<i64, &str> let _ = foo2(2i64, "abc"); - //~ MONO_ITEM fn generic_functions::foo2[0]<&str, usize> + //~ MONO_ITEM fn foo2::<&str, usize> let _ = foo2("a", 2usize); - //~ MONO_ITEM fn generic_functions::foo2[0]<char, ()> + //~ MONO_ITEM fn foo2::<char, ()> let _ = foo2('v', ()); - //~ MONO_ITEM fn generic_functions::foo3[0]<i32, i32, i32> + //~ MONO_ITEM fn foo3::<i32, i32, i32> let _ = foo3(2i32, 2i32, 2i32); - //~ MONO_ITEM fn generic_functions::foo3[0]<i64, &str, char> + //~ MONO_ITEM fn foo3::<i64, &str, char> let _ = foo3(2i64, "abc", 'c'); - //~ MONO_ITEM fn generic_functions::foo3[0]<i16, &str, usize> + //~ MONO_ITEM fn foo3::<i16, &str, usize> let _ = foo3(0i16, "a", 2usize); - //~ MONO_ITEM fn generic_functions::foo3[0]<char, (), ()> + //~ MONO_ITEM fn foo3::<char, (), ()> let _ = foo3('v', (), ()); 0 diff --git a/src/test/codegen-units/item-collection/generic-impl.rs b/src/test/codegen-units/item-collection/generic-impl.rs index 571bb4fa867..dd5367ef038 100644 --- a/src/test/codegen-units/item-collection/generic-impl.rs +++ b/src/test/codegen-units/item-collection/generic-impl.rs @@ -30,41 +30,41 @@ pub struct LifeTimeOnly<'a> { impl<'a> LifeTimeOnly<'a> { - //~ MONO_ITEM fn generic_impl::{{impl}}[1]::foo[0] + //~ MONO_ITEM fn LifeTimeOnly::foo pub fn foo(&self) {} - //~ MONO_ITEM fn generic_impl::{{impl}}[1]::bar[0] + //~ MONO_ITEM fn LifeTimeOnly::bar pub fn bar(&'a self) {} - //~ MONO_ITEM fn generic_impl::{{impl}}[1]::baz[0] + //~ MONO_ITEM fn LifeTimeOnly::baz pub fn baz<'b>(&'b self) {} pub fn non_instantiated<T>(&self) {} } -//~ MONO_ITEM fn generic_impl::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<i32> - //~ MONO_ITEM fn generic_impl::id[0]<i32> - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<i32, i16> + //~ MONO_ITEM fn Struct::<i32>::new + //~ MONO_ITEM fn id::<i32> + //~ MONO_ITEM fn Struct::<i32>::get::<i16> let _ = Struct::new(0i32).get(0i16); - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<i64> - //~ MONO_ITEM fn generic_impl::id[0]<i64> - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<i64, i16> + //~ MONO_ITEM fn Struct::<i64>::new + //~ MONO_ITEM fn id::<i64> + //~ MONO_ITEM fn Struct::<i64>::get::<i16> let _ = Struct::new(0i64).get(0i16); - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<char> - //~ MONO_ITEM fn generic_impl::id[0]<char> - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<char, i16> + //~ MONO_ITEM fn Struct::<char>::new + //~ MONO_ITEM fn id::<char> + //~ MONO_ITEM fn Struct::<char>::get::<i16> let _ = Struct::new('c').get(0i16); - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<&str> - //~ MONO_ITEM fn generic_impl::id[0]<&str> - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::get[0]<generic_impl::Struct[0]<&str>, i16> + //~ MONO_ITEM fn Struct::<&str>::new + //~ MONO_ITEM fn id::<&str> + //~ MONO_ITEM fn Struct::<Struct<&str>>::get::<i16> let _ = Struct::new(Struct::new("str")).get(0i16); - //~ MONO_ITEM fn generic_impl::{{impl}}[0]::new[0]<generic_impl::Struct[0]<&str>> - //~ MONO_ITEM fn generic_impl::id[0]<generic_impl::Struct[0]<&str>> + //~ MONO_ITEM fn Struct::<Struct<&str>>::new + //~ MONO_ITEM fn id::<Struct<&str>> let _ = (Struct::new(Struct::new("str")).f)(Struct::new("str")); 0 diff --git a/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs b/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs index e45644cd375..c01398eb234 100644 --- a/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs +++ b/src/test/codegen-units/item-collection/impl-in-non-instantiated-generic.rs @@ -11,14 +11,14 @@ trait SomeTrait { // discovered. pub fn generic_function<T>(x: T) -> (T, i32) { impl SomeTrait for i64 { - //~ MONO_ITEM fn impl_in_non_instantiated_generic::generic_function[0]::{{impl}}[0]::foo[0] + //~ MONO_ITEM fn generic_function::<impl SomeTrait for i64>::foo fn foo(&self) {} } (x, 0) } -//~ MONO_ITEM fn impl_in_non_instantiated_generic::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { 0i64.foo(); diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs index db0390b58c8..63966a7ec97 100644 --- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs +++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs @@ -19,20 +19,20 @@ impl<T> Trait for Struct<T> { fn bar(&self) {} } -//~ MONO_ITEM fn instantiation_through_vtable::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { let s1 = Struct { _a: 0u32 }; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal] - //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u32> - //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u32> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<Struct<u32>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal] + //~ MONO_ITEM fn <Struct<u32> as Trait>::foo + //~ MONO_ITEM fn <Struct<u32> as Trait>::bar let _ = &s1 as &Trait; let s1 = Struct { _a: 0u64 }; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal] - //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u64> - //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u64> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<Struct<u64>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal] + //~ MONO_ITEM fn <Struct<u64> as Trait>::foo + //~ MONO_ITEM fn <Struct<u64> as Trait>::bar let _ = &s1 as &Trait; 0 diff --git a/src/test/codegen-units/item-collection/items-within-generic-items.rs b/src/test/codegen-units/item-collection/items-within-generic-items.rs index 10bc52f6a8d..d37d7f7d9b2 100644 --- a/src/test/codegen-units/item-collection/items-within-generic-items.rs +++ b/src/test/codegen-units/item-collection/items-within-generic-items.rs @@ -4,13 +4,13 @@ #![feature(start)] fn generic_fn<T>(a: T) -> (T, i32) { - //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]::nested_fn[0] + //~ MONO_ITEM fn generic_fn::nested_fn fn nested_fn(a: i32) -> i32 { a + 1 } let x = { - //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]::nested_fn[1] + //~ MONO_ITEM fn generic_fn::nested_fn fn nested_fn(a: i32) -> i32 { a + 2 } @@ -21,14 +21,14 @@ fn generic_fn<T>(a: T) -> (T, i32) { return (a, x + nested_fn(0)); } -//~ MONO_ITEM fn items_within_generic_items::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]<i64> + //~ MONO_ITEM fn generic_fn::<i64> let _ = generic_fn(0i64); - //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]<u16> + //~ MONO_ITEM fn generic_fn::<u16> let _ = generic_fn(0u16); - //~ MONO_ITEM fn items_within_generic_items::generic_fn[0]<i8> + //~ MONO_ITEM fn generic_fn::<i8> let _ = generic_fn(0i8); 0 diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs index a899b8b2c8b..b5837716814 100644 --- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs @@ -5,13 +5,13 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<StructWithDrop> - shim(Some(StructWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal] struct StructWithDrop { x: i32 } impl Drop for StructWithDrop { - //~ MONO_ITEM fn non_generic_drop_glue::{{impl}}[0]::drop[0] + //~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop fn drop(&mut self) {} } @@ -19,13 +19,13 @@ struct StructNoDrop { x: i32 } -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<EnumWithDrop> - shim(Some(EnumWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal] enum EnumWithDrop { A(i32) } impl Drop for EnumWithDrop { - //~ MONO_ITEM fn non_generic_drop_glue::{{impl}}[1]::drop[0] + //~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop fn drop(&mut self) {} } @@ -33,7 +33,7 @@ enum EnumNoDrop { A(i32) } -//~ MONO_ITEM fn non_generic_drop_glue::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { let _ = StructWithDrop { x: 0 }.x; diff --git a/src/test/codegen-units/item-collection/non-generic-functions.rs b/src/test/codegen-units/item-collection/non-generic-functions.rs index 26d2fb1b421..092e64562c5 100644 --- a/src/test/codegen-units/item-collection/non-generic-functions.rs +++ b/src/test/codegen-units/item-collection/non-generic-functions.rs @@ -3,24 +3,24 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn non_generic_functions::foo[0] +//~ MONO_ITEM fn foo fn foo() { { - //~ MONO_ITEM fn non_generic_functions::foo[0]::foo[0] + //~ MONO_ITEM fn foo::foo fn foo() {} foo(); } { - //~ MONO_ITEM fn non_generic_functions::foo[0]::foo[1] + //~ MONO_ITEM fn foo::foo fn foo() {} foo(); } } -//~ MONO_ITEM fn non_generic_functions::bar[0] +//~ MONO_ITEM fn bar fn bar() { - //~ MONO_ITEM fn non_generic_functions::bar[0]::baz[0] + //~ MONO_ITEM fn bar::baz fn baz() {} baz(); } @@ -28,38 +28,38 @@ fn bar() { struct Struct { _x: i32 } impl Struct { - //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::foo[0] + //~ MONO_ITEM fn Struct::foo fn foo() { { - //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::foo[0]::foo[0] + //~ MONO_ITEM fn Struct::foo::foo fn foo() {} foo(); } { - //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::foo[0]::foo[1] + //~ MONO_ITEM fn Struct::foo::foo fn foo() {} foo(); } } - //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::bar[0] + //~ MONO_ITEM fn Struct::bar fn bar(&self) { { - //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::bar[0]::foo[0] + //~ MONO_ITEM fn Struct::bar::foo fn foo() {} foo(); } { - //~ MONO_ITEM fn non_generic_functions::{{impl}}[0]::bar[0]::foo[1] + //~ MONO_ITEM fn Struct::bar::foo fn foo() {} foo(); } } } -//~ MONO_ITEM fn non_generic_functions::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { foo(); diff --git a/src/test/codegen-units/item-collection/overloaded-operators.rs b/src/test/codegen-units/item-collection/overloaded-operators.rs index 0b4c97723d6..2be7eba1d84 100644 --- a/src/test/codegen-units/item-collection/overloaded-operators.rs +++ b/src/test/codegen-units/item-collection/overloaded-operators.rs @@ -12,7 +12,7 @@ pub struct Indexable { impl Index<usize> for Indexable { type Output = u8; - //~ MONO_ITEM fn overloaded_operators::{{impl}}[0]::index[0] + //~ MONO_ITEM fn <Indexable as std::ops::Index<usize>>::index fn index(&self, index: usize) -> &Self::Output { if index >= 3 { &self.data[0] @@ -23,7 +23,7 @@ impl Index<usize> for Indexable { } impl IndexMut<usize> for Indexable { - //~ MONO_ITEM fn overloaded_operators::{{impl}}[1]::index_mut[0] + //~ MONO_ITEM fn <Indexable as std::ops::IndexMut<usize>>::index_mut fn index_mut(&mut self, index: usize) -> &mut Self::Output { if index >= 3 { &mut self.data[0] @@ -34,8 +34,8 @@ impl IndexMut<usize> for Indexable { } -//~ MONO_ITEM fn overloaded_operators::{{impl}}[5]::eq[0] -//~ MONO_ITEM fn overloaded_operators::{{impl}}[5]::ne[0] +//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::eq +//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::ne #[derive(PartialEq)] pub struct Equatable(u32); @@ -43,7 +43,7 @@ pub struct Equatable(u32); impl Add<u32> for Equatable { type Output = u32; - //~ MONO_ITEM fn overloaded_operators::{{impl}}[2]::add[0] + //~ MONO_ITEM fn <Equatable as std::ops::Add<u32>>::add fn add(self, rhs: u32) -> u32 { self.0 + rhs } @@ -52,7 +52,7 @@ impl Add<u32> for Equatable { impl Deref for Equatable { type Target = u32; - //~ MONO_ITEM fn overloaded_operators::{{impl}}[3]::deref[0] + //~ MONO_ITEM fn <Equatable as std::ops::Deref>::deref fn deref(&self) -> &Self::Target { &self.0 } diff --git a/src/test/codegen-units/item-collection/static-init.rs b/src/test/codegen-units/item-collection/static-init.rs index 9d79171c4cb..287ec8f24eb 100644 --- a/src/test/codegen-units/item-collection/static-init.rs +++ b/src/test/codegen-units/item-collection/static-init.rs @@ -6,10 +6,10 @@ pub static FN : fn() = foo::<i32>; pub fn foo<T>() { } -//~ MONO_ITEM fn static_init::foo[0]<T> -//~ MONO_ITEM static static_init::FN[0] +//~ MONO_ITEM fn foo::<T> +//~ MONO_ITEM static FN -//~ MONO_ITEM fn static_init::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { 0 diff --git a/src/test/codegen-units/item-collection/statics-and-consts.rs b/src/test/codegen-units/item-collection/statics-and-consts.rs index 7e28ba58b63..49a8d3dff63 100644 --- a/src/test/codegen-units/item-collection/statics-and-consts.rs +++ b/src/test/codegen-units/item-collection/statics-and-consts.rs @@ -37,7 +37,7 @@ fn foo() { }; } -//~ MONO_ITEM fn statics_and_consts::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { foo(); @@ -46,9 +46,9 @@ fn start(_: isize, _: *const *const u8) -> isize { 0 } -//~ MONO_ITEM static statics_and_consts::STATIC1[0] +//~ MONO_ITEM static STATIC1 -//~ MONO_ITEM fn statics_and_consts::foo[0] -//~ MONO_ITEM static statics_and_consts::foo[0]::STATIC2[0] -//~ MONO_ITEM static statics_and_consts::foo[0]::STATIC2[1] -//~ MONO_ITEM static statics_and_consts::foo[0]::STATIC2[2] +//~ MONO_ITEM fn foo +//~ MONO_ITEM static foo::STATIC2 +//~ MONO_ITEM static foo::STATIC2 +//~ MONO_ITEM static foo::STATIC2 diff --git a/src/test/codegen-units/item-collection/trait-implementations.rs b/src/test/codegen-units/item-collection/trait-implementations.rs index f090c0c8d13..a816cb03241 100644 --- a/src/test/codegen-units/item-collection/trait-implementations.rs +++ b/src/test/codegen-units/item-collection/trait-implementations.rs @@ -10,7 +10,7 @@ pub trait SomeTrait { impl SomeTrait for i64 { - //~ MONO_ITEM fn trait_implementations::{{impl}}[0]::foo[0] + //~ MONO_ITEM fn <i64 as SomeTrait>::foo fn foo(&self) {} fn bar<T>(&self, _: T) {} @@ -18,7 +18,7 @@ impl SomeTrait for i64 { impl SomeTrait for i32 { - //~ MONO_ITEM fn trait_implementations::{{impl}}[1]::foo[0] + //~ MONO_ITEM fn <i32 as SomeTrait>::foo fn foo(&self) {} fn bar<T>(&self, _: T) {} @@ -32,7 +32,7 @@ pub trait SomeGenericTrait<T> { // Concrete impl of generic trait impl SomeGenericTrait<u32> for f64 { - //~ MONO_ITEM fn trait_implementations::{{impl}}[2]::foo[0] + //~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::foo fn foo(&self, _: u32) {} fn bar<T2>(&self, _: u32, _: T2) {} @@ -45,28 +45,28 @@ impl<T> SomeGenericTrait<T> for f32 { fn bar<T2>(&self, _: T, _: T2) {} } -//~ MONO_ITEM fn trait_implementations::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn trait_implementations::{{impl}}[1]::bar[0]<char> + //~ MONO_ITEM fn <i32 as SomeTrait>::bar::<char> 0i32.bar('x'); - //~ MONO_ITEM fn trait_implementations::{{impl}}[2]::bar[0]<&str> + //~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<&str> 0f64.bar(0u32, "&str"); - //~ MONO_ITEM fn trait_implementations::{{impl}}[2]::bar[0]<()> + //~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<()> 0f64.bar(0u32, ()); - //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::foo[0]<char> + //~ MONO_ITEM fn <f32 as SomeGenericTrait<char>>::foo 0f32.foo('x'); - //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::foo[0]<i64> + //~ MONO_ITEM fn <f32 as SomeGenericTrait<i64>>::foo 0f32.foo(-1i64); - //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::bar[0]<u32, ()> + //~ MONO_ITEM fn <f32 as SomeGenericTrait<u32>>::bar::<()> 0f32.bar(0u32, ()); - //~ MONO_ITEM fn trait_implementations::{{impl}}[3]::bar[0]<&str, &str> + //~ MONO_ITEM fn <f32 as SomeGenericTrait<&str>>::bar::<&str> 0f32.bar("&str", "&str"); 0 diff --git a/src/test/codegen-units/item-collection/trait-method-as-argument.rs b/src/test/codegen-units/item-collection/trait-method-as-argument.rs index 27ace8e31ad..6817b33c611 100644 --- a/src/test/codegen-units/item-collection/trait-method-as-argument.rs +++ b/src/test/codegen-units/item-collection/trait-method-as-argument.rs @@ -1,3 +1,4 @@ +// ignore-tidy-linelength // compile-flags:-Zprint-mono-items=eager #![deny(dead_code)] @@ -26,33 +27,33 @@ fn take_foo_mut<T, F: FnMut(T) -> T>(mut f: F, arg: T) -> T { (f)(arg) } -//~ MONO_ITEM fn trait_method_as_argument::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn trait_method_as_argument::take_foo_once[0]<u32, fn(u32) -> u32> - //~ MONO_ITEM fn trait_method_as_argument::{{impl}}[0]::foo[0] - //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(u32) -> u32, (u32)> + //~ MONO_ITEM fn take_foo_once::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}> + //~ MONO_ITEM fn <u32 as Trait>::foo + //~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnOnce<(u32,)>>::call_once - shim(fn(u32) -> u32 {<u32 as Trait>::foo}) take_foo_once(Trait::foo, 0u32); - //~ MONO_ITEM fn trait_method_as_argument::take_foo_once[0]<char, fn(char) -> char> - //~ MONO_ITEM fn trait_method_as_argument::Trait[0]::foo[0]<char> - //~ MONO_ITEM fn core::ops[0]::function[0]::FnOnce[0]::call_once[0]<fn(char) -> char, (char)> + //~ MONO_ITEM fn take_foo_once::<char, fn(char) -> char {<char as Trait>::foo}> + //~ MONO_ITEM fn <char as Trait>::foo + //~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnOnce<(char,)>>::call_once - shim(fn(char) -> char {<char as Trait>::foo}) take_foo_once(Trait::foo, 'c'); - //~ MONO_ITEM fn trait_method_as_argument::take_foo[0]<u32, fn(u32) -> u32> - //~ MONO_ITEM fn core::ops[0]::function[0]::Fn[0]::call[0]<fn(u32) -> u32, (u32)> + //~ MONO_ITEM fn take_foo::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}> + //~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::Fn<(u32,)>>::call - shim(fn(u32) -> u32 {<u32 as Trait>::foo}) take_foo(Trait::foo, 0u32); - //~ MONO_ITEM fn trait_method_as_argument::take_foo[0]<char, fn(char) -> char> - //~ MONO_ITEM fn core::ops[0]::function[0]::Fn[0]::call[0]<fn(char) -> char, (char)> + //~ MONO_ITEM fn take_foo::<char, fn(char) -> char {<char as Trait>::foo}> + //~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::Fn<(char,)>>::call - shim(fn(char) -> char {<char as Trait>::foo}) take_foo(Trait::foo, 'c'); - //~ MONO_ITEM fn trait_method_as_argument::take_foo_mut[0]<u32, fn(u32) -> u32> - //~ MONO_ITEM fn core::ops[0]::function[0]::FnMut[0]::call_mut[0]<fn(char) -> char, (char)> + //~ MONO_ITEM fn take_foo_mut::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}> + //~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnMut<(u32,)>>::call_mut - shim(fn(u32) -> u32 {<u32 as Trait>::foo}) take_foo_mut(Trait::foo, 0u32); - //~ MONO_ITEM fn trait_method_as_argument::take_foo_mut[0]<char, fn(char) -> char> - //~ MONO_ITEM fn core::ops[0]::function[0]::FnMut[0]::call_mut[0]<fn(u32) -> u32, (u32)> + //~ MONO_ITEM fn take_foo_mut::<char, fn(char) -> char {<char as Trait>::foo}> + //~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnMut<(char,)>>::call_mut - shim(fn(char) -> char {<char as Trait>::foo}) take_foo_mut(Trait::foo, 'c'); 0 diff --git a/src/test/codegen-units/item-collection/trait-method-default-impl.rs b/src/test/codegen-units/item-collection/trait-method-default-impl.rs index 6cf59fdc396..bfcdb6fa142 100644 --- a/src/test/codegen-units/item-collection/trait-method-default-impl.rs +++ b/src/test/codegen-units/item-collection/trait-method-default-impl.rs @@ -13,7 +13,7 @@ impl SomeTrait for i8 { // For the non-generic foo(), we should generate a codegen-item even if it // is not called anywhere - //~ MONO_ITEM fn trait_method_default_impl::SomeTrait[0]::foo[0]<i8> + //~ MONO_ITEM fn <i8 as SomeTrait>::foo } trait SomeGenericTrait<T1> { @@ -27,7 +27,7 @@ impl SomeGenericTrait<u64> for i32 { // For the non-generic foo(), we should generate a codegen-item even if it // is not called anywhere - //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::foo[0]<i32, T1> + //~ MONO_ITEM fn <i32 as SomeGenericTrait<T1>>::foo } // Non-generic impl of generic trait @@ -36,25 +36,25 @@ impl<T1> SomeGenericTrait<T1> for u32 { // since nothing is monomorphic here, nothing should be generated unless used somewhere. } -//~ MONO_ITEM fn trait_method_default_impl::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn trait_method_default_impl::SomeTrait[0]::bar[0]<i8, char> + //~ MONO_ITEM fn <i8 as SomeTrait>::bar::<char> let _ = 1i8.bar('c'); - //~ MONO_ITEM fn trait_method_default_impl::SomeTrait[0]::bar[0]<i8, &str> + //~ MONO_ITEM fn <i8 as SomeTrait>::bar::<&str> let _ = 2i8.bar("&str"); - //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<i32, u64, char> + //~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<char> 0i32.bar(0u64, 'c'); - //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<i32, u64, &str> + //~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<&str> 0i32.bar(0u64, "&str"); - //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<u32, i8, &[char; 1]> + //~ MONO_ITEM fn <u32 as SomeGenericTrait<i8>>::bar::<&[char; 1]> 0u32.bar(0i8, &['c']); - //~ MONO_ITEM fn trait_method_default_impl::SomeGenericTrait[0]::bar[0]<u32, i16, ()> + //~ MONO_ITEM fn <u32 as SomeGenericTrait<i16>>::bar::<()> 0u32.bar(0i16, ()); 0 diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs index 7e29af43538..c0489a6a259 100644 --- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs +++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs @@ -5,15 +5,15 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal] struct Root(Intermediate); -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal] struct Intermediate(Leaf); -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal] struct Leaf; impl Drop for Leaf { - //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[0]::drop[0] + //~ MONO_ITEM fn <Leaf as std::ops::Drop>::drop fn drop(&mut self) {} } @@ -25,21 +25,21 @@ impl<T> Drop for LeafGen<T> { fn drop(&mut self) {} } -//~ MONO_ITEM fn transitive_drop_glue::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { let _ = Root(Intermediate(Leaf)); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<RootGen<u32>> - shim(Some(RootGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<IntermediateGen<u32>> - shim(Some(IntermediateGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<LeafGen<u32>> - shim(Some(LeafGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn <LeafGen<u32> as std::ops::Drop>::drop let _ = RootGen(IntermediateGen(LeafGen(0u32))); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16> + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<RootGen<i16>> - shim(Some(RootGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<IntermediateGen<i16>> - shim(Some(IntermediateGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<LeafGen<i16>> - shim(Some(LeafGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn <LeafGen<i16> as std::ops::Drop>::drop let _ = RootGen(IntermediateGen(LeafGen(0i16))); 0 diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs index d77de53ce01..d34835ae691 100644 --- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs +++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs @@ -5,22 +5,22 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Dropped> - shim(Some(Dropped)) @@ tuple_drop_glue-cgu.0[Internal] struct Dropped; impl Drop for Dropped { - //~ MONO_ITEM fn tuple_drop_glue::{{impl}}[0]::drop[0] + //~ MONO_ITEM fn <Dropped as std::ops::Drop>::drop fn drop(&mut self) {} } -//~ MONO_ITEM fn tuple_drop_glue::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(u32, Dropped)> - shim(Some((u32, Dropped))) @@ tuple_drop_glue-cgu.0[Internal] let x = (0u32, Dropped); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(i16, (Dropped, bool))> - shim(Some((i16, (Dropped, bool)))) @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(Dropped, bool)> - shim(Some((Dropped, bool))) @@ tuple_drop_glue-cgu.0[Internal] let x = (0i16, (Dropped, true)); 0 diff --git a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs index ec6be0ecf43..17b92eae00d 100644 --- a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs +++ b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs @@ -3,7 +3,7 @@ #![deny(dead_code)] #![crate_type = "rlib"] -//~ MONO_ITEM fn unreferenced_const_fn::foo[0] @@ unreferenced_const_fn-cgu.0[External] +//~ MONO_ITEM fn foo @@ unreferenced_const_fn-cgu.0[External] pub const fn foo(x: u32) -> u32 { x + 0xf00 } diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs index 1ed60dcf265..9421bf106ba 100644 --- a/src/test/codegen-units/item-collection/unsizing.rs +++ b/src/test/codegen-units/item-collection/unsizing.rs @@ -43,19 +43,19 @@ struct Wrapper<T: ?Sized>(*const T); impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {} -//~ MONO_ITEM fn unsizing::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { // simple case let bool_sized = &true; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal] - //~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<bool> - shim(None) @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn <bool as Trait>::foo let _bool_unsized = bool_sized as &Trait; let char_sized = &'a'; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing-cgu.0[Internal] - //~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<char> - shim(None) @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn <char as Trait>::foo let _char_unsized = char_sized as &Trait; // struct field @@ -64,14 +64,14 @@ fn start(_: isize, _: *const *const u8) -> isize { _b: 2, _c: 3.0f64 }; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal] - //~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<f64> - shim(None) @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn <f64 as Trait>::foo let _struct_unsized = struct_sized as &Struct<Trait>; // custom coercion let wrapper_sized = Wrapper(&0u32); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal] - //~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<u32> - shim(None) @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn <u32 as Trait>::foo let _wrapper_sized = wrapper_sized as Wrapper<Trait>; 0 diff --git a/src/test/codegen-units/item-collection/unused-traits-and-generics.rs b/src/test/codegen-units/item-collection/unused-traits-and-generics.rs index 4a5e294ea0f..561dc1a5c07 100644 --- a/src/test/codegen-units/item-collection/unused-traits-and-generics.rs +++ b/src/test/codegen-units/item-collection/unused-traits-and-generics.rs @@ -74,4 +74,4 @@ impl NonGeneric { } // Only the non-generic methods should be instantiated: -//~ MONO_ITEM fn unused_traits_and_generics::{{impl}}[3]::foo[0] +//~ MONO_ITEM fn NonGeneric::foo diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index 1cb85382239..3de1bdb86c1 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -12,13 +12,13 @@ // aux-build:cgu_extern_drop_glue.rs extern crate cgu_extern_drop_glue; -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue-fallback.cgu[External] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<cgu_extern_drop_glue::Struct> - shim(Some(cgu_extern_drop_glue::Struct)) @@ extern_drop_glue-fallback.cgu[External] struct LocalStruct(cgu_extern_drop_glue::Struct); -//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External] +//~ MONO_ITEM fn user @@ extern_drop_glue[External] pub fn user() { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<LocalStruct> - shim(Some(LocalStruct)) @@ extern_drop_glue-fallback.cgu[External] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } @@ -27,9 +27,9 @@ pub mod mod1 { struct LocalStruct(cgu_extern_drop_glue::Struct); - //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External] + //~ MONO_ITEM fn mod1::user @@ extern_drop_glue-mod1[External] pub fn user() { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<mod1::LocalStruct> - shim(Some(mod1::LocalStruct)) @@ extern_drop_glue-fallback.cgu[External] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } } diff --git a/src/test/codegen-units/partitioning/extern-generic.rs b/src/test/codegen-units/partitioning/extern-generic.rs index 88d6116a987..02930f96bd1 100644 --- a/src/test/codegen-units/partitioning/extern-generic.rs +++ b/src/test/codegen-units/partitioning/extern-generic.rs @@ -9,7 +9,7 @@ // aux-build:cgu_generic_function.rs extern crate cgu_generic_function; -//~ MONO_ITEM fn extern_generic::user[0] @@ extern_generic[Internal] +//~ MONO_ITEM fn user @@ extern_generic[Internal] fn user() { let _ = cgu_generic_function::foo("abc"); } @@ -17,7 +17,7 @@ fn user() { mod mod1 { use cgu_generic_function; - //~ MONO_ITEM fn extern_generic::mod1[0]::user[0] @@ extern_generic-mod1[Internal] + //~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[Internal] fn user() { let _ = cgu_generic_function::foo("abc"); } @@ -25,7 +25,7 @@ mod mod1 { mod mod1 { use cgu_generic_function; - //~ MONO_ITEM fn extern_generic::mod1[0]::mod1[0]::user[0] @@ extern_generic-mod1-mod1[Internal] + //~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[Internal] fn user() { let _ = cgu_generic_function::foo("abc"); } @@ -35,18 +35,18 @@ mod mod1 { mod mod2 { use cgu_generic_function; - //~ MONO_ITEM fn extern_generic::mod2[0]::user[0] @@ extern_generic-mod2[Internal] + //~ MONO_ITEM fn mod2::user @@ extern_generic-mod2[Internal] fn user() { let _ = cgu_generic_function::foo("abc"); } } mod mod3 { - //~ MONO_ITEM fn extern_generic::mod3[0]::non_user[0] @@ extern_generic-mod3[Internal] + //~ MONO_ITEM fn mod3::non_user @@ extern_generic-mod3[Internal] fn non_user() {} } // Make sure the two generic functions from the extern crate get instantiated // once for the current crate -//~ MONO_ITEM fn cgu_generic_function::foo[0]<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] -//~ MONO_ITEM fn cgu_generic_function::bar[0]<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] +//~ MONO_ITEM fn cgu_generic_function::foo::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] +//~ MONO_ITEM fn cgu_generic_function::bar::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] diff --git a/src/test/codegen-units/partitioning/incremental-merging.rs b/src/test/codegen-units/partitioning/incremental-merging.rs index ca2df19096e..91ae6022931 100644 --- a/src/test/codegen-units/partitioning/incremental-merging.rs +++ b/src/test/codegen-units/partitioning/incremental-merging.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=lazy -Cincremental=tmp/partitioning-tests/incremental-merging @@ -14,28 +13,28 @@ // while `ccc` and `ddd` are supposed to stay untouched. pub mod aaa { - //~ MONO_ITEM fn incremental_merging::aaa[0]::foo[0] @@ incremental_merging-aaa--incremental_merging-bbb[External] + //~ MONO_ITEM fn aaa::foo @@ incremental_merging-aaa--incremental_merging-bbb[External] pub fn foo(a: u64) -> u64 { a + 1 } } pub mod bbb { - //~ MONO_ITEM fn incremental_merging::bbb[0]::foo[0] @@ incremental_merging-aaa--incremental_merging-bbb[External] + //~ MONO_ITEM fn bbb::foo @@ incremental_merging-aaa--incremental_merging-bbb[External] pub fn foo(a: u64, b: u64) -> u64 { a + b + 1 } } pub mod ccc { - //~ MONO_ITEM fn incremental_merging::ccc[0]::foo[0] @@ incremental_merging-ccc[External] + //~ MONO_ITEM fn ccc::foo @@ incremental_merging-ccc[External] pub fn foo(a: u64, b: u64, c: u64) -> u64 { a + b + c + 1 } } pub mod ddd { - //~ MONO_ITEM fn incremental_merging::ddd[0]::foo[0] @@ incremental_merging-ddd[External] + //~ MONO_ITEM fn ddd::foo @@ incremental_merging-ddd[External] pub fn foo(a: u64, b: u64, c: u64, d: u64) -> u64 { a + b + c + d + 1 } diff --git a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs index 7afeb0a0f36..410b77b0050 100644 --- a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs +++ b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs @@ -12,10 +12,10 @@ extern crate cgu_explicit_inlining; // This test makes sure that items inlined from external crates are privately // instantiated in every codegen unit they are used in. -//~ MONO_ITEM fn cgu_explicit_inlining::inlined[0] @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal] -//~ MONO_ITEM fn cgu_explicit_inlining::always_inlined[0] @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal] +//~ MONO_ITEM fn cgu_explicit_inlining::inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal] +//~ MONO_ITEM fn cgu_explicit_inlining::always_inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal] -//~ MONO_ITEM fn inlining_from_extern_crate::user[0] @@ inlining_from_extern_crate[External] +//~ MONO_ITEM fn user @@ inlining_from_extern_crate[External] pub fn user() { cgu_explicit_inlining::inlined(); @@ -28,7 +28,7 @@ pub fn user() pub mod mod1 { use cgu_explicit_inlining; - //~ MONO_ITEM fn inlining_from_extern_crate::mod1[0]::user[0] @@ inlining_from_extern_crate-mod1[External] + //~ MONO_ITEM fn mod1::user @@ inlining_from_extern_crate-mod1[External] pub fn user() { cgu_explicit_inlining::inlined(); @@ -41,7 +41,7 @@ pub mod mod1 { pub mod mod2 { use cgu_explicit_inlining; - //~ MONO_ITEM fn inlining_from_extern_crate::mod2[0]::user[0] @@ inlining_from_extern_crate-mod2[External] + //~ MONO_ITEM fn mod2::user @@ inlining_from_extern_crate-mod2[External] pub fn user() { cgu_explicit_inlining::always_inlined(); diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index c082b408278..98108615ce9 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -8,22 +8,22 @@ #![allow(dead_code)] #![crate_type = "rlib"] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue-fallback.cgu[External] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Struct> - shim(Some(Struct)) @@ local_drop_glue-fallback.cgu[External] struct Struct { _a: u32, } impl Drop for Struct { - //~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue-fallback.cgu[External] + //~ MONO_ITEM fn <Struct as std::ops::Drop>::drop @@ local_drop_glue-fallback.cgu[External] fn drop(&mut self) {} } -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue-fallback.cgu[External] +//~ MONO_ITEM fn std::intrinsics::drop_in_place::<Outer> - shim(Some(Outer)) @@ local_drop_glue-fallback.cgu[External] struct Outer { _a: Struct, } -//~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External] +//~ MONO_ITEM fn user @@ local_drop_glue[External] pub fn user() { let _ = Outer { _a: Struct { _a: 0 } }; } @@ -31,14 +31,14 @@ pub fn user() { pub mod mod1 { use super::Struct; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-fallback.cgu[External] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<mod1::Struct2> - shim(Some(mod1::Struct2)) @@ local_drop_glue-fallback.cgu[External] struct Struct2 { _a: Struct, - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-fallback.cgu[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[Internal] _b: (u32, Struct), } - //~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External] + //~ MONO_ITEM fn mod1::user @@ local_drop_glue-mod1[External] pub fn user() { let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) }; } diff --git a/src/test/codegen-units/partitioning/local-generic.rs b/src/test/codegen-units/partitioning/local-generic.rs index 4518166a1c9..9a7743bbf46 100644 --- a/src/test/codegen-units/partitioning/local-generic.rs +++ b/src/test/codegen-units/partitioning/local-generic.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/local-generic @@ -6,13 +5,13 @@ #![allow(dead_code)] #![crate_type="lib"] -//~ MONO_ITEM fn local_generic::generic[0]<u32> @@ local_generic.volatile[External] -//~ MONO_ITEM fn local_generic::generic[0]<u64> @@ local_generic.volatile[External] -//~ MONO_ITEM fn local_generic::generic[0]<char> @@ local_generic.volatile[External] -//~ MONO_ITEM fn local_generic::generic[0]<&str> @@ local_generic.volatile[External] +//~ MONO_ITEM fn generic::<u32> @@ local_generic.volatile[External] +//~ MONO_ITEM fn generic::<u64> @@ local_generic.volatile[External] +//~ MONO_ITEM fn generic::<char> @@ local_generic.volatile[External] +//~ MONO_ITEM fn generic::<&str> @@ local_generic.volatile[External] pub fn generic<T>(x: T) -> T { x } -//~ MONO_ITEM fn local_generic::user[0] @@ local_generic[Internal] +//~ MONO_ITEM fn user @@ local_generic[Internal] fn user() { let _ = generic(0u32); } @@ -20,7 +19,7 @@ fn user() { mod mod1 { pub use super::generic; - //~ MONO_ITEM fn local_generic::mod1[0]::user[0] @@ local_generic-mod1[Internal] + //~ MONO_ITEM fn mod1::user @@ local_generic-mod1[Internal] fn user() { let _ = generic(0u64); } @@ -28,7 +27,7 @@ mod mod1 { mod mod1 { use super::generic; - //~ MONO_ITEM fn local_generic::mod1[0]::mod1[0]::user[0] @@ local_generic-mod1-mod1[Internal] + //~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[Internal] fn user() { let _ = generic('c'); } @@ -38,7 +37,7 @@ mod mod1 { mod mod2 { use super::generic; - //~ MONO_ITEM fn local_generic::mod2[0]::user[0] @@ local_generic-mod2[Internal] + //~ MONO_ITEM fn mod2::user @@ local_generic-mod2[Internal] fn user() { let _ = generic("abc"); } diff --git a/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs b/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs index 6322f55d2b7..a24943348f3 100644 --- a/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs +++ b/src/test/codegen-units/partitioning/local-inlining-but-not-all.rs @@ -9,7 +9,7 @@ mod inline { - //~ MONO_ITEM fn local_inlining_but_not_all::inline[0]::inlined_function[0] @@ local_inlining_but_not_all-inline[External] + //~ MONO_ITEM fn inline::inlined_function @@ local_inlining_but_not_all-inline[External] #[inline] pub fn inlined_function() { @@ -20,7 +20,7 @@ mod inline { pub mod user1 { use super::inline; - //~ MONO_ITEM fn local_inlining_but_not_all::user1[0]::foo[0] @@ local_inlining_but_not_all-user1[External] + //~ MONO_ITEM fn user1::foo @@ local_inlining_but_not_all-user1[External] pub fn foo() { inline::inlined_function(); } @@ -29,7 +29,7 @@ pub mod user1 { pub mod user2 { use super::inline; - //~ MONO_ITEM fn local_inlining_but_not_all::user2[0]::bar[0] @@ local_inlining_but_not_all-user2[External] + //~ MONO_ITEM fn user2::bar @@ local_inlining_but_not_all-user2[External] pub fn bar() { inline::inlined_function(); } @@ -37,7 +37,7 @@ pub mod user2 { pub mod non_user { - //~ MONO_ITEM fn local_inlining_but_not_all::non_user[0]::baz[0] @@ local_inlining_but_not_all-non_user[External] + //~ MONO_ITEM fn non_user::baz @@ local_inlining_but_not_all-non_user[External] pub fn baz() { } diff --git a/src/test/codegen-units/partitioning/local-inlining.rs b/src/test/codegen-units/partitioning/local-inlining.rs index d75dfc91262..0cc652eeb52 100644 --- a/src/test/codegen-units/partitioning/local-inlining.rs +++ b/src/test/codegen-units/partitioning/local-inlining.rs @@ -10,7 +10,7 @@ mod inline { // Important: This function should show up in all codegen units where it is inlined - //~ MONO_ITEM fn local_inlining::inline[0]::inlined_function[0] @@ local_inlining-user1[Internal] local_inlining-user2[Internal] + //~ MONO_ITEM fn inline::inlined_function @@ local_inlining-user1[Internal] local_inlining-user2[Internal] #[inline(always)] pub fn inlined_function() { @@ -21,7 +21,7 @@ mod inline { pub mod user1 { use super::inline; - //~ MONO_ITEM fn local_inlining::user1[0]::foo[0] @@ local_inlining-user1[External] + //~ MONO_ITEM fn user1::foo @@ local_inlining-user1[External] pub fn foo() { inline::inlined_function(); } @@ -30,7 +30,7 @@ pub mod user1 { pub mod user2 { use super::inline; - //~ MONO_ITEM fn local_inlining::user2[0]::bar[0] @@ local_inlining-user2[External] + //~ MONO_ITEM fn user2::bar @@ local_inlining-user2[External] pub fn bar() { inline::inlined_function(); } @@ -38,7 +38,7 @@ pub mod user2 { pub mod non_user { - //~ MONO_ITEM fn local_inlining::non_user[0]::baz[0] @@ local_inlining-non_user[External] + //~ MONO_ITEM fn non_user::baz @@ local_inlining-non_user[External] pub fn baz() { } diff --git a/src/test/codegen-units/partitioning/local-transitive-inlining.rs b/src/test/codegen-units/partitioning/local-transitive-inlining.rs index 3cf03966865..0c8a67aeb3d 100644 --- a/src/test/codegen-units/partitioning/local-transitive-inlining.rs +++ b/src/test/codegen-units/partitioning/local-transitive-inlining.rs @@ -9,7 +9,7 @@ mod inline { - //~ MONO_ITEM fn local_transitive_inlining::inline[0]::inlined_function[0] @@ local_transitive_inlining-indirect_user[Internal] + //~ MONO_ITEM fn inline::inlined_function @@ local_transitive_inlining-indirect_user[Internal] #[inline(always)] pub fn inlined_function() { @@ -20,7 +20,7 @@ mod inline { mod direct_user { use super::inline; - //~ MONO_ITEM fn local_transitive_inlining::direct_user[0]::foo[0] @@ local_transitive_inlining-indirect_user[Internal] + //~ MONO_ITEM fn direct_user::foo @@ local_transitive_inlining-indirect_user[Internal] #[inline(always)] pub fn foo() { inline::inlined_function(); @@ -30,7 +30,7 @@ mod direct_user { pub mod indirect_user { use super::direct_user; - //~ MONO_ITEM fn local_transitive_inlining::indirect_user[0]::bar[0] @@ local_transitive_inlining-indirect_user[External] + //~ MONO_ITEM fn indirect_user::bar @@ local_transitive_inlining-indirect_user[External] pub fn bar() { direct_user::foo(); } @@ -38,7 +38,7 @@ pub mod indirect_user { pub mod non_user { - //~ MONO_ITEM fn local_transitive_inlining::non_user[0]::baz[0] @@ local_transitive_inlining-non_user[External] + //~ MONO_ITEM fn non_user::baz @@ local_transitive_inlining-non_user[External] pub fn baz() { } diff --git a/src/test/codegen-units/partitioning/regular-modules.rs b/src/test/codegen-units/partitioning/regular-modules.rs index c8ceeafd0bf..f9b8f52b0bb 100644 --- a/src/test/codegen-units/partitioning/regular-modules.rs +++ b/src/test/codegen-units/partitioning/regular-modules.rs @@ -1,4 +1,3 @@ -// ignore-tidy-linelength // We specify -C incremental here because we want to test the partitioning for // incremental compilation // compile-flags:-Zprint-mono-items=eager -Cincremental=tmp/partitioning-tests/regular-modules @@ -6,67 +5,67 @@ #![allow(dead_code)] #![crate_type="lib"] -//~ MONO_ITEM fn regular_modules::foo[0] @@ regular_modules[Internal] +//~ MONO_ITEM fn foo @@ regular_modules[Internal] fn foo() {} -//~ MONO_ITEM fn regular_modules::bar[0] @@ regular_modules[Internal] +//~ MONO_ITEM fn bar @@ regular_modules[Internal] fn bar() {} -//~ MONO_ITEM static regular_modules::BAZ[0] @@ regular_modules[Internal] +//~ MONO_ITEM static BAZ @@ regular_modules[Internal] static BAZ: u64 = 0; mod mod1 { - //~ MONO_ITEM fn regular_modules::mod1[0]::foo[0] @@ regular_modules-mod1[Internal] + //~ MONO_ITEM fn mod1::foo @@ regular_modules-mod1[Internal] fn foo() {} - //~ MONO_ITEM fn regular_modules::mod1[0]::bar[0] @@ regular_modules-mod1[Internal] + //~ MONO_ITEM fn mod1::bar @@ regular_modules-mod1[Internal] fn bar() {} - //~ MONO_ITEM static regular_modules::mod1[0]::BAZ[0] @@ regular_modules-mod1[Internal] + //~ MONO_ITEM static mod1::BAZ @@ regular_modules-mod1[Internal] static BAZ: u64 = 0; mod mod1 { - //~ MONO_ITEM fn regular_modules::mod1[0]::mod1[0]::foo[0] @@ regular_modules-mod1-mod1[Internal] + //~ MONO_ITEM fn mod1::mod1::foo @@ regular_modules-mod1-mod1[Internal] fn foo() {} - //~ MONO_ITEM fn regular_modules::mod1[0]::mod1[0]::bar[0] @@ regular_modules-mod1-mod1[Internal] + //~ MONO_ITEM fn mod1::mod1::bar @@ regular_modules-mod1-mod1[Internal] fn bar() {} - //~ MONO_ITEM static regular_modules::mod1[0]::mod1[0]::BAZ[0] @@ regular_modules-mod1-mod1[Internal] + //~ MONO_ITEM static mod1::mod1::BAZ @@ regular_modules-mod1-mod1[Internal] static BAZ: u64 = 0; } mod mod2 { - //~ MONO_ITEM fn regular_modules::mod1[0]::mod2[0]::foo[0] @@ regular_modules-mod1-mod2[Internal] + //~ MONO_ITEM fn mod1::mod2::foo @@ regular_modules-mod1-mod2[Internal] fn foo() {} - //~ MONO_ITEM fn regular_modules::mod1[0]::mod2[0]::bar[0] @@ regular_modules-mod1-mod2[Internal] + //~ MONO_ITEM fn mod1::mod2::bar @@ regular_modules-mod1-mod2[Internal] fn bar() {} - //~ MONO_ITEM static regular_modules::mod1[0]::mod2[0]::BAZ[0] @@ regular_modules-mod1-mod2[Internal] + //~ MONO_ITEM static mod1::mod2::BAZ @@ regular_modules-mod1-mod2[Internal] static BAZ: u64 = 0; } } mod mod2 { - //~ MONO_ITEM fn regular_modules::mod2[0]::foo[0] @@ regular_modules-mod2[Internal] + //~ MONO_ITEM fn mod2::foo @@ regular_modules-mod2[Internal] fn foo() {} - //~ MONO_ITEM fn regular_modules::mod2[0]::bar[0] @@ regular_modules-mod2[Internal] + //~ MONO_ITEM fn mod2::bar @@ regular_modules-mod2[Internal] fn bar() {} - //~ MONO_ITEM static regular_modules::mod2[0]::BAZ[0] @@ regular_modules-mod2[Internal] + //~ MONO_ITEM static mod2::BAZ @@ regular_modules-mod2[Internal] static BAZ: u64 = 0; mod mod1 { - //~ MONO_ITEM fn regular_modules::mod2[0]::mod1[0]::foo[0] @@ regular_modules-mod2-mod1[Internal] + //~ MONO_ITEM fn mod2::mod1::foo @@ regular_modules-mod2-mod1[Internal] fn foo() {} - //~ MONO_ITEM fn regular_modules::mod2[0]::mod1[0]::bar[0] @@ regular_modules-mod2-mod1[Internal] + //~ MONO_ITEM fn mod2::mod1::bar @@ regular_modules-mod2-mod1[Internal] fn bar() {} - //~ MONO_ITEM static regular_modules::mod2[0]::mod1[0]::BAZ[0] @@ regular_modules-mod2-mod1[Internal] + //~ MONO_ITEM static mod2::mod1::BAZ @@ regular_modules-mod2-mod1[Internal] static BAZ: u64 = 0; } mod mod2 { - //~ MONO_ITEM fn regular_modules::mod2[0]::mod2[0]::foo[0] @@ regular_modules-mod2-mod2[Internal] + //~ MONO_ITEM fn mod2::mod2::foo @@ regular_modules-mod2-mod2[Internal] fn foo() {} - //~ MONO_ITEM fn regular_modules::mod2[0]::mod2[0]::bar[0] @@ regular_modules-mod2-mod2[Internal] + //~ MONO_ITEM fn mod2::mod2::bar @@ regular_modules-mod2-mod2[Internal] fn bar() {} - //~ MONO_ITEM static regular_modules::mod2[0]::mod2[0]::BAZ[0] @@ regular_modules-mod2-mod2[Internal] + //~ MONO_ITEM static mod2::mod2::BAZ @@ regular_modules-mod2-mod2[Internal] static BAZ: u64 = 0; } } diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs index 99142dd6b7e..eb3196439ba 100644 --- a/src/test/codegen-units/partitioning/shared-generics.rs +++ b/src/test/codegen-units/partitioning/shared-generics.rs @@ -9,10 +9,10 @@ // aux-build:shared_generics_aux.rs extern crate shared_generics_aux; -//~ MONO_ITEM fn shared_generics::foo[0] +//~ MONO_ITEM fn foo pub fn foo() { - //~ MONO_ITEM fn shared_generics_aux::generic_fn[0]<u16> @@ shared_generics_aux-in-shared_generics.volatile[External] + //~ MONO_ITEM fn shared_generics_aux::generic_fn::<u16> @@ shared_generics_aux-in-shared_generics.volatile[External] let _ = shared_generics_aux::generic_fn(0u16, 1u16); // This should not generate a monomorphization because it's already diff --git a/src/test/codegen-units/partitioning/statics.rs b/src/test/codegen-units/partitioning/statics.rs index 5eac046b810..02d6467577f 100644 --- a/src/test/codegen-units/partitioning/statics.rs +++ b/src/test/codegen-units/partitioning/statics.rs @@ -4,34 +4,34 @@ #![crate_type="rlib"] -//~ MONO_ITEM static statics::FOO[0] @@ statics[Internal] +//~ MONO_ITEM static FOO @@ statics[Internal] static FOO: u32 = 0; -//~ MONO_ITEM static statics::BAR[0] @@ statics[Internal] +//~ MONO_ITEM static BAR @@ statics[Internal] static BAR: u32 = 0; -//~ MONO_ITEM fn statics::function[0] @@ statics[External] +//~ MONO_ITEM fn function @@ statics[External] pub fn function() { - //~ MONO_ITEM static statics::function[0]::FOO[0] @@ statics[Internal] + //~ MONO_ITEM static function::FOO @@ statics[Internal] static FOO: u32 = 0; - //~ MONO_ITEM static statics::function[0]::BAR[0] @@ statics[Internal] + //~ MONO_ITEM static function::BAR @@ statics[Internal] static BAR: u32 = 0; } pub mod mod1 { - //~ MONO_ITEM static statics::mod1[0]::FOO[0] @@ statics-mod1[Internal] + //~ MONO_ITEM static mod1::FOO @@ statics-mod1[Internal] static FOO: u32 = 0; - //~ MONO_ITEM static statics::mod1[0]::BAR[0] @@ statics-mod1[Internal] + //~ MONO_ITEM static mod1::BAR @@ statics-mod1[Internal] static BAR: u32 = 0; - //~ MONO_ITEM fn statics::mod1[0]::function[0] @@ statics-mod1[External] + //~ MONO_ITEM fn mod1::function @@ statics-mod1[External] pub fn function() { - //~ MONO_ITEM static statics::mod1[0]::function[0]::FOO[0] @@ statics-mod1[Internal] + //~ MONO_ITEM static mod1::function::FOO @@ statics-mod1[Internal] static FOO: u32 = 0; - //~ MONO_ITEM static statics::mod1[0]::function[0]::BAR[0] @@ statics-mod1[Internal] + //~ MONO_ITEM static mod1::function::BAR @@ statics-mod1[Internal] static BAR: u32 = 0; } } diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs index 5a1d95d2669..03dbac6179d 100644 --- a/src/test/codegen-units/partitioning/vtable-through-const.rs +++ b/src/test/codegen-units/partitioning/vtable-through-const.rs @@ -28,7 +28,7 @@ mod mod1 { fn do_something_else(&self, x: T) -> T { x } } - //~ MONO_ITEM fn vtable_through_const::mod1[0]::id[0]<i64> @@ vtable_through_const-mod1.volatile[Internal] + //~ MONO_ITEM fn mod1::id::<i64> @@ vtable_through_const-mod1.volatile[Internal] fn id<T>(x: T) -> T { x } // These are referenced, so they produce mono-items (see start()) @@ -43,8 +43,8 @@ mod mod1 { fn do_something_else(&self) {} } - //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait2[0]::do_something[0]<u32> @@ vtable_through_const-mod1.volatile[Internal] - //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait2[0]::do_something_else[0]<u32> @@ vtable_through_const-mod1.volatile[Internal] + //~ MONO_ITEM fn <u32 as mod1::Trait2>::do_something @@ vtable_through_const-mod1.volatile[Internal] + //~ MONO_ITEM fn <u32 as mod1::Trait2>::do_something_else @@ vtable_through_const-mod1.volatile[Internal] impl Trait2 for u32 {} pub trait Trait2Gen<T> { @@ -63,30 +63,30 @@ mod mod1 { pub const ID_I64: fn(i64) -> i64 = id::<i64>; } -//~ MONO_ITEM fn vtable_through_const::start[0] +//~ MONO_ITEM fn start #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ vtable_through_const[Internal] + //~ MONO_ITEM fn std::intrinsics::drop_in_place::<u32> - shim(None) @@ vtable_through_const[Internal] // Since Trait1::do_something() is instantiated via its default implementation, // it is considered a generic and is instantiated here only because it is // referenced in this module. - //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait1[0]::do_something_else[0]<u32> @@ vtable_through_const-mod1.volatile[External] + //~ MONO_ITEM fn <u32 as mod1::Trait1>::do_something_else @@ vtable_through_const-mod1.volatile[External] // Although it is never used, Trait1::do_something_else() has to be // instantiated locally here too, otherwise the <&u32 as &Trait1> vtable // could not be fully constructed. - //~ MONO_ITEM fn vtable_through_const::mod1[0]::Trait1[0]::do_something[0]<u32> @@ vtable_through_const-mod1.volatile[External] + //~ MONO_ITEM fn <u32 as mod1::Trait1>::do_something @@ vtable_through_const-mod1.volatile[External] mod1::TRAIT1_REF.do_something(); // Same as above - //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[1]::do_something[0]<u8> @@ vtable_through_const-mod1.volatile[External] - //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[1]::do_something_else[0]<u8> @@ vtable_through_const-mod1.volatile[External] - //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[3]::do_something[0]<u8> @@ vtable_through_const-mod1.volatile[Internal] - //~ MONO_ITEM fn vtable_through_const::mod1[0]::{{impl}}[3]::do_something_else[0]<u8> @@ vtable_through_const-mod1.volatile[Internal] + //~ MONO_ITEM fn <u32 as mod1::Trait1Gen<u8>>::do_something @@ vtable_through_const-mod1.volatile[External] + //~ MONO_ITEM fn <u32 as mod1::Trait1Gen<u8>>::do_something_else @@ vtable_through_const-mod1.volatile[External] + //~ MONO_ITEM fn <u32 as mod1::Trait2Gen<u8>>::do_something @@ vtable_through_const-mod1.volatile[Internal] + //~ MONO_ITEM fn <u32 as mod1::Trait2Gen<u8>>::do_something_else @@ vtable_through_const-mod1.volatile[Internal] mod1::TRAIT1_GEN_REF.do_something(0u8); - //~ MONO_ITEM fn vtable_through_const::mod1[0]::id[0]<char> @@ vtable_through_const-mod1.volatile[External] + //~ MONO_ITEM fn mod1::id::<char> @@ vtable_through_const-mod1.volatile[External] mod1::ID_CHAR('x'); 0 diff --git a/src/test/codegen-units/polymorphization/unused_type_parameters.rs b/src/test/codegen-units/polymorphization/unused_type_parameters.rs index 403f68bb170..13be99635a5 100644 --- a/src/test/codegen-units/polymorphization/unused_type_parameters.rs +++ b/src/test/codegen-units/polymorphization/unused_type_parameters.rs @@ -1,5 +1,4 @@ // compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1 -// ignore-tidy-linelength #![crate_type = "rlib"] @@ -10,44 +9,44 @@ mod functions { // Function doesn't have any type parameters to be unused. pub fn no_parameters() {} -//~ MONO_ITEM fn unused_type_parameters::functions[0]::no_parameters[0] +//~ MONO_ITEM fn functions::no_parameters // Function has an unused type parameter. pub fn unused<T>() { } -//~ MONO_ITEM fn unused_type_parameters::functions[0]::unused[0]<T> +//~ MONO_ITEM fn functions::unused::<T> // Function uses type parameter in value of a binding. pub fn used_binding_value<T: Default>() { let _: T = Default::default(); } -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_value[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_value[0]<u64> +//~ MONO_ITEM fn functions::used_binding_value::<u32> +//~ MONO_ITEM fn functions::used_binding_value::<u64> // Function uses type parameter in type of a binding. pub fn used_binding_type<T>() { let _: Option<T> = None; } -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_type[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_binding_type[0]<u64> +//~ MONO_ITEM fn functions::used_binding_type::<u32> +//~ MONO_ITEM fn functions::used_binding_type::<u64> // Function uses type parameter in argument. pub fn used_argument<T>(_: T) { } -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_argument[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_argument[0]<u64> +//~ MONO_ITEM fn functions::used_argument::<u32> +//~ MONO_ITEM fn functions::used_argument::<u64> // // Function uses type parameter in substitutions to another function. pub fn used_substs<T>() { unused::<T>() } -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_substs[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::functions[0]::used_substs[0]<u64> +//~ MONO_ITEM fn functions::used_substs::<u32> +//~ MONO_ITEM fn functions::used_substs::<u64> } @@ -57,7 +56,7 @@ mod closures { let _ = || {}; } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::no_parameters[0] +//~ MONO_ITEM fn closures::no_parameters // Function has an unused type parameter in parent and closure. pub fn unused<T>() -> u32 { @@ -65,8 +64,8 @@ mod closures { add_one(3) } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::unused[0]::{{closure}}[0]<T, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::unused[0]<T> +//~ MONO_ITEM fn closures::unused::<T>::{{closure}}#0 +//~ MONO_ITEM fn closures::unused::<T> // Function has an unused type parameter in closure, but not in parent. pub fn used_parent<T: Default>() -> u32 { @@ -75,9 +74,9 @@ mod closures { add_one(3) } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_parent[0]::{{closure}}[0]<T, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_parent[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_parent[0]<u64> +//~ MONO_ITEM fn closures::used_parent::<T>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_parent::<u32> +//~ MONO_ITEM fn closures::used_parent::<u64> // Function uses type parameter in value of a binding in closure. pub fn used_binding_value<T: Default>() -> T { @@ -89,10 +88,10 @@ mod closures { x() } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()) -> u64, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_value[0]<u64> +//~ MONO_ITEM fn closures::used_binding_value::<u32>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_binding_value::<u64>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_binding_value::<u32> +//~ MONO_ITEM fn closures::used_binding_value::<u64> // Function uses type parameter in type of a binding in closure. pub fn used_binding_type<T>() -> Option<T> { @@ -104,10 +103,10 @@ mod closures { x() } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()) -> core::option[0]::Option[0]<u32>, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()) -> core::option[0]::Option[0]<u64>, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_binding_type[0]<u64> +//~ MONO_ITEM fn closures::used_binding_type::<u32>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_binding_type::<u64>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_binding_type::<u32> +//~ MONO_ITEM fn closures::used_binding_type::<u64> // Function and closure uses type parameter in argument. pub fn used_argument<T>(t: T) -> u32 { @@ -115,10 +114,10 @@ mod closures { x(t) } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn((u64)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument[0]<u64> +//~ MONO_ITEM fn closures::used_argument::<u32>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_argument::<u64>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_argument::<u32> +//~ MONO_ITEM fn closures::used_argument::<u64> // Closure uses type parameter in argument. pub fn used_argument_closure<T: Default>() -> u32 { @@ -127,10 +126,10 @@ mod closures { x(t) } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn((u64)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_argument_closure[0]<u64> +//~ MONO_ITEM fn closures::used_argument_closure::<u32>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_argument_closure::<u64>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_argument_closure::<u32> +//~ MONO_ITEM fn closures::used_argument_closure::<u64> // Closure uses type parameter as upvar. pub fn used_upvar<T: Default>() -> T { @@ -139,10 +138,10 @@ mod closures { y() } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]::{{closure}}[0]<u32, i32, extern "rust-call" fn(()) -> u32, (u32)> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]::{{closure}}[0]<u64, i32, extern "rust-call" fn(()) -> u64, (u64)> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_upvar[0]<u64> +//~ MONO_ITEM fn closures::used_upvar::<u32>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_upvar::<u64>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_upvar::<u32> +//~ MONO_ITEM fn closures::used_upvar::<u64> // Closure uses type parameter in substitutions to another function. pub fn used_substs<T>() { @@ -150,10 +149,10 @@ mod closures { x() } -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()), ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()), ()> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::closures[0]::used_substs[0]<u64> +//~ MONO_ITEM fn closures::used_substs::<u32>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_substs::<u64>::{{closure}}#0 +//~ MONO_ITEM fn closures::used_substs::<u32> +//~ MONO_ITEM fn closures::used_substs::<u64> } mod methods { @@ -164,29 +163,29 @@ mod methods { pub fn unused_impl() { } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::unused_impl[0]<F> +//~ MONO_ITEM fn methods::Foo::<F>::unused_impl // Function has an unused type parameter from impl and fn. pub fn unused_both<G: Default>() { } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::unused_both[0]<F, G> +//~ MONO_ITEM fn methods::Foo::<F>::unused_both::<G> // Function uses type parameter from impl. pub fn used_impl() { let _: F = Default::default(); } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_impl[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_impl[0]<u64> +//~ MONO_ITEM fn methods::Foo::<u32>::used_impl +//~ MONO_ITEM fn methods::Foo::<u64>::used_impl // Function uses type parameter from impl. pub fn used_fn<G: Default>() { let _: G = Default::default(); } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_fn[0]<F, u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_fn[0]<F, u64> +//~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u32> +//~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u64> // Function uses type parameter from impl. pub fn used_both<G: Default>() { @@ -194,16 +193,16 @@ mod methods { let _: G = Default::default(); } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_both[0]<u32, u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_both[0]<u64, u64> +//~ MONO_ITEM fn methods::Foo::<u32>::used_both::<u32> +//~ MONO_ITEM fn methods::Foo::<u64>::used_both::<u64> // Function uses type parameter in substitutions to another function. pub fn used_substs() { super::functions::unused::<F>() } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_substs[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::used_substs[0]<u64> +//~ MONO_ITEM fn methods::Foo::<u32>::used_substs +//~ MONO_ITEM fn methods::Foo::<u64>::used_substs // Function has an unused type parameter from impl and fn. pub fn closure_unused_all<G: Default>() -> u32 { @@ -211,8 +210,8 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_unused_all[0]::{{closure}}[0]<F, G, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_unused_all[0]<F, G> +//~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G> // Function uses type parameter from impl and fn in closure. pub fn closure_used_both<G: Default>() -> u32 { @@ -225,10 +224,10 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]::{{closure}}[0]<u32, u32, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]::{{closure}}[0]<u64, u64, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]<u32, u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_both[0]<u64, u64> +//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32> +//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64> // Function uses type parameter from fn in closure. pub fn closure_used_fn<G: Default>() -> u32 { @@ -240,10 +239,10 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]::{{closure}}[0]<F, u32, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]::{{closure}}[0]<F, u64, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]<F, u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_fn[0]<F, u64> +//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32> +//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64> // Function uses type parameter from impl in closure. pub fn closure_used_impl<G: Default>() -> u32 { @@ -255,10 +254,10 @@ mod methods { add_one(3) } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]::{{closure}}[0]<u32, G, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]::{{closure}}[0]<u64, G, i8, extern "rust-call" fn((u32)) -> u32, ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]<u32, G> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_impl[0]<u64, G> +//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G> +//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G> // Closure uses type parameter in substitutions to another function. pub fn closure_used_substs() { @@ -266,10 +265,10 @@ mod methods { x() } -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]::{{closure}}[0]<u32, i8, extern "rust-call" fn(()), ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]::{{closure}}[0]<u64, i8, extern "rust-call" fn(()), ()> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::methods[0]::{{impl}}[0]::closure_used_substs[0]<u64> +//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs::{{closure}}#0 +//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs +//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs } } @@ -306,8 +305,8 @@ fn dispatch<T: Default>() { let _ = methods::Foo::<T>::closure_used_substs(); } -//~ MONO_ITEM fn unused_type_parameters::dispatch[0]<u32> -//~ MONO_ITEM fn unused_type_parameters::dispatch[0]<u64> +//~ MONO_ITEM fn dispatch::<u32> +//~ MONO_ITEM fn dispatch::<u64> pub fn foo() { // Generate two copies of each function to check that where the type parameter is unused, @@ -316,8 +315,8 @@ pub fn foo() { dispatch::<u64>(); } -//~ MONO_ITEM fn unused_type_parameters::foo[0] @@ unused_type_parameters-cgu.0[External] +//~ MONO_ITEM fn foo @@ unused_type_parameters-cgu.0[External] // These are all the items that aren't relevant to the test. -//~ MONO_ITEM fn core::default[0]::{{impl}}[6]::default[0] -//~ MONO_ITEM fn core::default[0]::{{impl}}[7]::default[0] +//~ MONO_ITEM fn <u32 as std::default::Default>::default +//~ MONO_ITEM fn <u64 as std::default::Default>::default diff --git a/src/test/codegen/enum-bounds-check-derived-idx.rs b/src/test/codegen/enum-bounds-check-derived-idx.rs new file mode 100644 index 00000000000..7e3773b6a3e --- /dev/null +++ b/src/test/codegen/enum-bounds-check-derived-idx.rs @@ -0,0 +1,25 @@ +// This test checks an optimization that is not guaranteed to work. This test case should not block +// a future LLVM update. +// compile-flags: -O +// min-llvm-version: 11.0 + +#![crate_type = "lib"] + +pub enum Bar { + A = 1, + B = 3, +} + +// CHECK-LABEL: @lookup_inc +#[no_mangle] +pub fn lookup_inc(buf: &[u8; 5], f: Bar) -> u8 { + // CHECK-NOT: panic_bounds_check + buf[f as usize + 1] +} + +// CHECK-LABEL: @lookup_dec +#[no_mangle] +pub fn lookup_dec(buf: &[u8; 5], f: Bar) -> u8 { + // CHECK-NOT: panic_bounds_check + buf[f as usize - 1] +} diff --git a/src/test/codegen/enum-bounds-check-issue-13926.rs b/src/test/codegen/enum-bounds-check-issue-13926.rs new file mode 100644 index 00000000000..ad029f0fa73 --- /dev/null +++ b/src/test/codegen/enum-bounds-check-issue-13926.rs @@ -0,0 +1,19 @@ +// This test checks an optimization that is not guaranteed to work. This test case should not block +// a future LLVM update. +// compile-flags: -O +// min-llvm-version: 11.0 + +#![crate_type = "lib"] + +#[repr(u8)] +pub enum Exception { + Low = 5, + High = 10, +} + +// CHECK-LABEL: @access +#[no_mangle] +pub fn access(array: &[usize; 12], exc: Exception) -> usize { + // CHECK-NOT: panic_bounds_check + array[(exc as u8 - 4) as usize] +} diff --git a/src/test/codegen/enum-bounds-check.rs b/src/test/codegen/enum-bounds-check.rs index 21a27c9f35d..17322d5911b 100644 --- a/src/test/codegen/enum-bounds-check.rs +++ b/src/test/codegen/enum-bounds-check.rs @@ -12,3 +12,15 @@ pub fn lookup(buf: &[u8; 2], f: Foo) -> u8 { // CHECK-NOT: panic_bounds_check buf[f as usize] } + +pub enum Bar { + A = 2, + B = 3 +} + +// CHECK-LABEL: @lookup_unmodified +#[no_mangle] +pub fn lookup_unmodified(buf: &[u8; 5], f: Bar) -> u8 { + // CHECK-NOT: panic_bounds_check + buf[f as usize] +} diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline-async.rs new file mode 100644 index 00000000000..5c838159b98 --- /dev/null +++ b/src/test/mir-opt/inline/inline-async.rs @@ -0,0 +1,18 @@ +// Checks that inliner doesn't introduce cycles when optimizing generators. +// The outcome of optimization is not verfied, just the absence of the cycle. +// Regression test for #76181. +// +// edition:2018 + +#![crate_type = "lib"] + +pub struct S; + +impl S { + pub async fn g(&mut self) { + self.h(); + } + pub fn h(&mut self) { + let _ = self.g(); + } +} diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview-block.rs new file mode 100644 index 00000000000..fc1d6e0ede6 --- /dev/null +++ b/src/test/mir-opt/spanview-block.rs @@ -0,0 +1,5 @@ +// Test spanview block output +// compile-flags: -Z dump-mir-spanview=block + +// EMIT_MIR spanview_block.main.mir_map.0.html +fn main() {} diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview-statement.rs new file mode 100644 index 00000000000..a43ad5e71a3 --- /dev/null +++ b/src/test/mir-opt/spanview-statement.rs @@ -0,0 +1,5 @@ +// Test spanview output (the default value for `-Z dump-mir-spanview` is "statement") +// compile-flags: -Z dump-mir-spanview + +// EMIT_MIR spanview_statement.main.mir_map.0.html +fn main() {} diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview-terminator.rs new file mode 100644 index 00000000000..92e1411eadb --- /dev/null +++ b/src/test/mir-opt/spanview-terminator.rs @@ -0,0 +1,5 @@ +// Test spanview terminator output +// compile-flags: -Z dump-mir-spanview=terminator + +// EMIT_MIR spanview_terminator.main.mir_map.0.html +fn main() {} diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.mir_map.0.html new file mode 100644 index 00000000000..7c1b7bc3b84 --- /dev/null +++ b/src/test/mir-opt/spanview_block.main.mir_map.0.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html> +<head> + <title>coverage_of_if_else - Code Regions</title> + <style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } + </style> +</head> +<body> +<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="bb0: $DIR/spanview-block.rs:5:11: 5:13: + 5:11-5:13: Assign: _0 = const () + 5:13-5:13: Goto: goto -> bb2"><span class="annotation">@bb0:</span> {}</span></span><span><span class="code even" style="--layer: 1" title="bb2: $DIR/spanview-block.rs:5:13: 5:13: + 5:13-5:13: Return: return"><span class="annotation">@bb2</span></span></span></span></div> +</body> +</html> diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.mir_map.0.html new file mode 100644 index 00000000000..f8662a3277a --- /dev/null +++ b/src/test/mir-opt/spanview_statement.main.mir_map.0.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html> +<head> + <title>coverage_of_if_else - Code Regions</title> + <style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } + </style> +</head> +<body> +<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="bb0[0]: $DIR/spanview-statement.rs:5:11: 5:13: + 5:11-5:13: Assign: _0 = const ()"><span class="annotation">@bb0[0]:</span> {}</span></span><span><span class="code even" style="--layer: 1" title="bb0`Goto`: $DIR/spanview-statement.rs:5:13: 5:13: + 5:13-5:13: Goto: goto -> bb2"><span class="annotation">@bb0`Goto`</span></span></span><span><span class="code even" style="--layer: 1" title="bb2`Return`: $DIR/spanview-statement.rs:5:13: 5:13: + 5:13-5:13: Return: return"><span class="annotation">@bb2`Return`</span></span></span></span></div> +</body> +</html> diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html new file mode 100644 index 00000000000..d0a11a8d262 --- /dev/null +++ b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> + <title>coverage_of_if_else - Code Regions</title> + <style> + .line { + counter-increment: line; + } + .line:before { + content: counter(line) ": "; + font-family: Menlo, Monaco, monospace; + font-style: italic; + width: 3.8em; + display: inline-block; + text-align: right; + filter: opacity(50%); + -webkit-user-select: none; + } + .code { + color: #dddddd; + background-color: #222222; + font-family: Menlo, Monaco, monospace; + line-height: 1.4em; + border-bottom: 2px solid #222222; + white-space: pre; + display: inline-block; + } + .odd { + background-color: #55bbff; + color: #223311; + } + .even { + background-color: #ee7756; + color: #551133; + } + .code { + --index: calc(var(--layer) - 1); + padding-top: calc(var(--index) * 0.15em); + filter: + hue-rotate(calc(var(--index) * 25deg)) + saturate(calc(100% - (var(--index) * 2%))) + brightness(calc(100% - (var(--index) * 1.5%))); + } + .annotation { + color: #4444ff; + font-family: monospace; + font-style: italic; + display: none; + -webkit-user-select: none; + } + body:active .annotation { + /* requires holding mouse down anywhere on the page */ + display: inline-block; + } + span:hover .annotation { + /* requires hover over a span ONLY on its first line */ + display: inline-block; + } + </style> +</head> +<body> +<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="bb0`Goto`: $DIR/spanview-terminator.rs:5:13: 5:13: + 5:13-5:13: Goto: goto -> bb2"><span class="annotation">@bb0`Goto`</span></span></span><span><span class="code even" style="--layer: 1" title="bb2`Return`: $DIR/spanview-terminator.rs:5:13: 5:13: + 5:13-5:13: Return: return"><span class="annotation">@bb2`Return`</span></span></span></span></div> +</body> +</html> diff --git a/src/test/rustdoc/index-page.rs b/src/test/rustdoc/index-page.rs index f0476f083b8..be668a1276a 100644 --- a/src/test/rustdoc/index-page.rs +++ b/src/test/rustdoc/index-page.rs @@ -6,6 +6,6 @@ // @has foo/../index.html // @has - '//span[@class="in-band"]' 'List of all crates' -// @has - '//ul[@class="mod"]//a[@href="foo/index.html"]' 'foo' -// @has - '//ul[@class="mod"]//a[@href="all_item_types/index.html"]' 'all_item_types' +// @has - '//ul[@class="crate mod"]//a[@href="foo/index.html"]' 'foo' +// @has - '//ul[@class="crate mod"]//a[@href="all_item_types/index.html"]' 'all_item_types' pub struct Foo; diff --git a/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs index 75bf320dd5b..7a88c3df2e4 100644 --- a/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs +++ b/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs @@ -1,7 +1,7 @@ // Test that attempt to reborrow an `&mut` pointer in an aliasable // location yields an error. // -// Example from src/librustc_borrowck/borrowck/README.md +// Example from compiler/rustc_borrowck/borrowck/README.md fn foo(t0: & &mut isize) { let t1 = t0; diff --git a/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs index 2839a9195a0..5ef282c0ca0 100644 --- a/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs +++ b/src/test/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs @@ -5,7 +5,7 @@ // Test that freezing an `&mut` pointer while referent is // frozen is legal. // -// Example from src/librustc_borrowck/borrowck/README.md +// Example from compiler/rustc_borrowck/borrowck/README.md // pretty-expanded FIXME #23616 diff --git a/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs b/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs index 10fc1437253..fa2d5531b13 100644 --- a/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs +++ b/src/test/ui/borrowck/borrowck-move-mut-base-ptr.rs @@ -1,7 +1,7 @@ // Test that attempt to move `&mut` pointer while pointee is borrowed // yields an error. // -// Example from src/librustc_borrowck/borrowck/README.md +// Example from compiler/rustc_borrowck/borrowck/README.md diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs b/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs index 32caa466475..6174893bae9 100644 --- a/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs +++ b/src/test/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs @@ -1,7 +1,7 @@ // Test that attempt to mutably borrow `&mut` pointer while pointee is // borrowed yields an error. // -// Example from src/librustc_borrowck/borrowck/README.md +// Example from compiler/rustc_borrowck/borrowck/README.md diff --git a/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs b/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs index 3d40d319226..8170323efc5 100644 --- a/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs +++ b/src/test/ui/borrowck/borrowck-swap-mut-base-ptr.rs @@ -1,7 +1,7 @@ // Test that attempt to swap `&mut` pointer while pointee is borrowed // yields an error. // -// Example from src/librustc_borrowck/borrowck/README.md +// Example from compiler/rustc_borrowck/borrowck/README.md use std::mem::swap; diff --git a/src/test/ui/codemap_tests/bad-format-args.rs b/src/test/ui/codemap_tests/bad-format-args.rs index dff248344a5..e89a45a84f5 100644 --- a/src/test/ui/codemap_tests/bad-format-args.rs +++ b/src/test/ui/codemap_tests/bad-format-args.rs @@ -1,5 +1,5 @@ fn main() { format!(); //~ ERROR requires at least a format string argument - format!("" 1); //~ ERROR expected token: `,` + format!("" 1); //~ ERROR expected `,`, found `1` format!("", 1 1); //~ ERROR expected one of } diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr index 96d7b07b0e2..5ed023e1f21 100644 --- a/src/test/ui/codemap_tests/bad-format-args.stderr +++ b/src/test/ui/codemap_tests/bad-format-args.stderr @@ -6,7 +6,7 @@ LL | format!(); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: expected token: `,` +error: expected `,`, found `1` --> $DIR/bad-format-args.rs:3:16 | LL | format!("" 1); diff --git a/src/test/ui/const-generics/argument_order.stderr b/src/test/ui/const-generics/argument_order.full.stderr index d6546a768d2..b52e5050703 100644 --- a/src/test/ui/const-generics/argument_order.stderr +++ b/src/test/ui/const-generics/argument_order.full.stderr @@ -1,11 +1,11 @@ error: lifetime parameters must be declared prior to const parameters - --> $DIR/argument_order.rs:9:32 + --> $DIR/argument_order.rs:12:32 | LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> { | -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>` error[E0747]: lifetime provided when a type was expected - --> $DIR/argument_order.rs:16:23 + --> $DIR/argument_order.rs:20:23 | LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>; | ^^^^^^^ diff --git a/src/test/ui/const-generics/argument_order.min.stderr b/src/test/ui/const-generics/argument_order.min.stderr new file mode 100644 index 00000000000..728ae69b41f --- /dev/null +++ b/src/test/ui/const-generics/argument_order.min.stderr @@ -0,0 +1,30 @@ +error: type parameters must be declared prior to const parameters + --> $DIR/argument_order.rs:6:28 + | +LL | struct Bad<const N: usize, T> { + | -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>` + +error: lifetime parameters must be declared prior to const parameters + --> $DIR/argument_order.rs:12:32 + | +LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> { + | -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>` + +error: type parameters must be declared prior to const parameters + --> $DIR/argument_order.rs:12:36 + | +LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> { + | ---------------------^----------------------^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>` + +error[E0747]: lifetime provided when a type was expected + --> $DIR/argument_order.rs:20:23 + | +LL | let _: AlsoBad<7, 'static, u32, 'static, 17, u16>; + | ^^^^^^^ + | + = note: lifetime arguments must be provided before type arguments + = help: reorder the arguments: lifetimes, then types, then consts: `<'a, 'b, T, U, N, M>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/const-generics/argument_order.rs b/src/test/ui/const-generics/argument_order.rs index 9e071e674e7..507baf5fd75 100644 --- a/src/test/ui/const-generics/argument_order.rs +++ b/src/test/ui/const-generics/argument_order.rs @@ -1,13 +1,17 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Bad<const N: usize, T> { + //[min]~^ ERROR type parameters must be declared prior to const parameters arr: [u8; { N }], another: T, } struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> { //~^ ERROR lifetime parameters must be declared prior + //[min]~^^ ERROR type parameters must be declared prior to const parameters a: &'a T, b: &'b U, } diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs index 49fc53b32bd..390b6cc2049 100644 --- a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs +++ b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs @@ -1,7 +1,8 @@ // run-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] #![allow(dead_code)] diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr b/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr deleted file mode 100644 index e6eb2a0a783..00000000000 --- a/src/test/ui/const-generics/array-wrapper-struct-ctor.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/array-wrapper-struct-ctor.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs index aac5d195f76..931f6ade7f1 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -1,6 +1,8 @@ // check-pass -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] // This test confirms that the types can be inferred correctly for this example with const // generics. Previously this would ICE, and more recently error. diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr deleted file mode 100644 index c5c48d7be46..00000000000 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cannot-infer-type-for-const-param.rs:2:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr index 2e2bfed51fb..3827002ff4b 100644 --- a/src/test/ui/const-generics/const-arg-type-arg-misordered.stderr +++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr @@ -1,5 +1,5 @@ error[E0747]: constant provided when a type was expected - --> $DIR/const-arg-type-arg-misordered.rs:6:35 + --> $DIR/const-arg-type-arg-misordered.rs:8:35 | LL | fn foo<const N: usize>() -> Array<N, ()> { | ^ diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr new file mode 100644 index 00000000000..2c5fc8dcc01 --- /dev/null +++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr @@ -0,0 +1,12 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/const-arg-type-arg-misordered.rs:8:35 + | +LL | fn foo<const N: usize>() -> Array<N, ()> { + | ^ + | + = note: type arguments must be provided before constant arguments + = help: reorder the arguments: types, then consts: `<T, N>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs index 13ca56ad3e6..6680f772fa3 100644 --- a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs +++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs @@ -1,9 +1,12 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] type Array<T, const N: usize> = [T; N]; -fn foo<const N: usize>() -> Array<N, ()> { //~ ERROR constant provided when a type was expected +fn foo<const N: usize>() -> Array<N, ()> { + //~^ ERROR constant provided when a type was expected unimplemented!() } diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.full.stderr index 1194dd30f61..c2acaabbd88 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.stderr +++ b/src/test/ui/const-generics/const-param-before-other-params.full.stderr @@ -1,5 +1,5 @@ error: lifetime parameters must be declared prior to const parameters - --> $DIR/const-param-before-other-params.rs:4:21 + --> $DIR/const-param-before-other-params.rs:6:21 | LL | fn bar<const X: (), 'a>(_: &'a ()) { | --------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const X: ()>` diff --git a/src/test/ui/const-generics/const-param-before-other-params.min.stderr b/src/test/ui/const-generics/const-param-before-other-params.min.stderr new file mode 100644 index 00000000000..c7e6d1be421 --- /dev/null +++ b/src/test/ui/const-generics/const-param-before-other-params.min.stderr @@ -0,0 +1,32 @@ +error: lifetime parameters must be declared prior to const parameters + --> $DIR/const-param-before-other-params.rs:6:21 + | +LL | fn bar<const X: (), 'a>(_: &'a ()) { + | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` + +error: type parameters must be declared prior to const parameters + --> $DIR/const-param-before-other-params.rs:11:21 + | +LL | fn foo<const X: (), T>(_: &T) {} + | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>` + +error: `()` is forbidden as the type of a const generic parameter + --> $DIR/const-param-before-other-params.rs:6:17 + | +LL | fn bar<const X: (), 'a>(_: &'a ()) { + | ^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `()` is forbidden as the type of a const generic parameter + --> $DIR/const-param-before-other-params.rs:11:17 + | +LL | fn foo<const X: (), T>(_: &T) {} + | ^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs index 0d787d9a67b..f1be90cf2e4 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.rs +++ b/src/test/ui/const-generics/const-param-before-other-params.rs @@ -1,10 +1,15 @@ -#![allow(incomplete_features)] -#![feature(const_generics)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] fn bar<const X: (), 'a>(_: &'a ()) { //~^ ERROR lifetime parameters must be declared prior to const parameters + //[min]~^^ ERROR `()` is forbidden as the type of a const generic parameter } fn foo<const X: (), T>(_: &T) {} +//[min]~^ ERROR type parameters must be declared prior to const parameters +//[min]~^^ ERROR `()` is forbidden as the type of a const generic parameter fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr new file mode 100644 index 00000000000..a20c7264acf --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr @@ -0,0 +1,9 @@ +error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter + --> $DIR/issue-63322-forbid-dyn.rs:10:18 + | +LL | fn test<const T: &'static dyn A>() { + | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr new file mode 100644 index 00000000000..e6d9fb7a246 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr @@ -0,0 +1,18 @@ +error: `&'static (dyn A + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/issue-63322-forbid-dyn.rs:10:18 + | +LL | fn test<const T: &'static dyn A>() { + | ^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter + --> $DIR/issue-63322-forbid-dyn.rs:10:18 + | +LL | fn test<const T: &'static dyn A>() { + | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs index 2bcaa27b4d2..2194eb97a41 100644 --- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait A {} struct B; @@ -7,6 +9,7 @@ impl A for B {} fn test<const T: &'static dyn A>() { //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used + //[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden unimplemented!() } diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr deleted file mode 100644 index 32054e43716..00000000000 --- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr +++ /dev/null @@ -1,18 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-63322-forbid-dyn.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter - --> $DIR/issue-63322-forbid-dyn.rs:8:18 - | -LL | fn test<const T: &'static dyn A>() { - | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` - -error: aborting due to previous error; 1 warning emitted - -For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/const-generics/issues/issue-64494.stderr b/src/test/ui/const-generics/issues/issue-64494.full.stderr index 30dca169643..a97ec9308f8 100644 --- a/src/test/ui/const-generics/issues/issue-64494.stderr +++ b/src/test/ui/const-generics/issues/issue-64494.full.stderr @@ -1,5 +1,5 @@ error: constant expression depends on a generic parameter - --> $DIR/issue-64494.rs:14:53 + --> $DIR/issue-64494.rs:16:53 | LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} | ^^^^ @@ -7,7 +7,7 @@ LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} = note: this may fail depending on what value the parameter takes error: constant expression depends on a generic parameter - --> $DIR/issue-64494.rs:16:53 + --> $DIR/issue-64494.rs:19:53 | LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} | ^^^^ diff --git a/src/test/ui/const-generics/issues/issue-64494.min.stderr b/src/test/ui/const-generics/issues/issue-64494.min.stderr new file mode 100644 index 00000000000..69fe0974a79 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-64494.min.stderr @@ -0,0 +1,28 @@ +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/issue-64494.rs:16:38 + | +LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} + | ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T` + | + = help: it is currently only allowed to use either `T` or `{ T }` as generic constants + +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/issue-64494.rs:19:38 + | +LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} + | ^^^^^^ non-trivial anonymous constants must not depend on the parameter `T` + | + = help: it is currently only allowed to use either `T` or `{ T }` as generic constants + +error[E0119]: conflicting implementations of trait `MyTrait`: + --> $DIR/issue-64494.rs:19:1 + | +LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} + | ------------------------------------ first implementation here +... +LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/const-generics/issues/issue-64494.rs b/src/test/ui/const-generics/issues/issue-64494.rs index 4c755530b99..3b598a41522 100644 --- a/src/test/ui/const-generics/issues/issue-64494.rs +++ b/src/test/ui/const-generics/issues/issue-64494.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait Foo { const VAL: usize; @@ -12,8 +14,11 @@ struct Is<const T: bool>; impl True for Is<{true}> {} impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {} -//~^ ERROR constant expression depends on a generic parameter +//[full]~^ ERROR constant expression depends on a generic parameter +//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {} -//~^ ERROR constant expression depends on a generic parameter +//[full]~^ ERROR constant expression depends on a generic parameter +//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values +//[min]~| ERROR conflicting implementations of trait `MyTrait` fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-64519.rs b/src/test/ui/const-generics/issues/issue-64519.rs index e9391096b04..1ca709d0975 100644 --- a/src/test/ui/const-generics/issues/issue-64519.rs +++ b/src/test/ui/const-generics/issues/issue-64519.rs @@ -1,7 +1,8 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Foo<const D: usize> { state: Option<[u8; D]>, diff --git a/src/test/ui/const-generics/issues/issue-66205.full.stderr b/src/test/ui/const-generics/issues/issue-66205.full.stderr new file mode 100644 index 00000000000..a1520912e4e --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-66205.full.stderr @@ -0,0 +1,10 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-66205.rs:8:12 + | +LL | fact::<{ N - 1 }>(); + | ^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-66205.min.stderr b/src/test/ui/const-generics/issues/issue-66205.min.stderr new file mode 100644 index 00000000000..86709c389b6 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-66205.min.stderr @@ -0,0 +1,10 @@ +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/issue-66205.rs:8:14 + | +LL | fact::<{ N - 1 }>(); + | ^ non-trivial anonymous constants must not depend on the parameter `N` + | + = help: it is currently only allowed to use either `N` or `{ N }` as generic constants + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-66205.rs b/src/test/ui/const-generics/issues/issue-66205.rs index 7cedf51ca04..e115eff356a 100644 --- a/src/test/ui/const-generics/issues/issue-66205.rs +++ b/src/test/ui/const-generics/issues/issue-66205.rs @@ -1,10 +1,13 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] #![allow(dead_code, unconditional_recursion)] -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete fn fact<const N: usize>() { fact::<{ N - 1 }>(); - //~^ ERROR constant expression depends on a generic parameter + //[full]~^ ERROR constant expression depends on a generic parameter + //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-66205.stderr b/src/test/ui/const-generics/issues/issue-66205.stderr deleted file mode 100644 index 1e9c0f2f3d9..00000000000 --- a/src/test/ui/const-generics/issues/issue-66205.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-66205.rs:2:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -error: constant expression depends on a generic parameter - --> $DIR/issue-66205.rs:6:12 - | -LL | fact::<{ N - 1 }>(); - | ^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to previous error; 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-66906.rs b/src/test/ui/const-generics/issues/issue-66906.rs index 486c72d8a34..3e048593c9b 100644 --- a/src/test/ui/const-generics/issues/issue-66906.rs +++ b/src/test/ui/const-generics/issues/issue-66906.rs @@ -1,7 +1,8 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] pub struct Tuple; diff --git a/src/test/ui/const-generics/issues/issue-66906.stderr b/src/test/ui/const-generics/issues/issue-66906.stderr deleted file mode 100644 index 8e8b552f90e..00000000000 --- a/src/test/ui/const-generics/issues/issue-66906.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-66906.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-67185-1.rs b/src/test/ui/const-generics/issues/issue-67185-1.rs index b08057851a1..09d88ef89a3 100644 --- a/src/test/ui/const-generics/issues/issue-67185-1.rs +++ b/src/test/ui/const-generics/issues/issue-67185-1.rs @@ -1,7 +1,8 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait Baz { type Quaks; diff --git a/src/test/ui/const-generics/issues/issue-67185-1.stderr b/src/test/ui/const-generics/issues/issue-67185-1.stderr deleted file mode 100644 index 9cc797d6d8a..00000000000 --- a/src/test/ui/const-generics/issues/issue-67185-1.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-67185-1.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-68596.rs b/src/test/ui/const-generics/issues/issue-68596.rs index 1f96e7d3b41..3b27d4d68c5 100644 --- a/src/test/ui/const-generics/issues/issue-68596.rs +++ b/src/test/ui/const-generics/issues/issue-68596.rs @@ -1,6 +1,8 @@ // check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] pub struct S(u8); diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr b/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr new file mode 100644 index 00000000000..81c8f4392c7 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr @@ -0,0 +1,11 @@ +error: `[usize; 0]` is forbidden as the type of a const generic parameter + --> $DIR/issue-68615-adt.rs:7:23 + | +LL | struct Const<const V: [usize; 0]> {} + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.rs b/src/test/ui/const-generics/issues/issue-68615-adt.rs index 140bb28ec5a..d616f3ab95a 100644 --- a/src/test/ui/const-generics/issues/issue-68615-adt.rs +++ b/src/test/ui/const-generics/issues/issue-68615-adt.rs @@ -1,8 +1,11 @@ -// check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Const<const V: [usize; 0]> {} +//[min]~^ ERROR `[usize; 0]` is forbidden as the type of a const generic parameter type MyConst = Const<{ [] }>; fn main() { diff --git a/src/test/ui/const-generics/issues/issue-68615-array.min.stderr b/src/test/ui/const-generics/issues/issue-68615-array.min.stderr new file mode 100644 index 00000000000..8f55a92fce9 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-68615-array.min.stderr @@ -0,0 +1,11 @@ +error: `[usize; 0]` is forbidden as the type of a const generic parameter + --> $DIR/issue-68615-array.rs:7:21 + | +LL | struct Foo<const V: [usize; 0] > {} + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-68615-array.rs b/src/test/ui/const-generics/issues/issue-68615-array.rs index c384bc1e36d..24c9a59a185 100644 --- a/src/test/ui/const-generics/issues/issue-68615-array.rs +++ b/src/test/ui/const-generics/issues/issue-68615-array.rs @@ -1,8 +1,11 @@ -// check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Foo<const V: [usize; 0] > {} +//[min]~^ ERROR `[usize; 0]` is forbidden as the type of a const generic parameter type MyFoo = Foo<{ [] }>; diff --git a/src/test/ui/const-generics/issues/issue-68977.full.stderr b/src/test/ui/const-generics/issues/issue-68977.full.stderr new file mode 100644 index 00000000000..3690bac3eb3 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-68977.full.stderr @@ -0,0 +1,10 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-68977.rs:35:44 + | +LL | FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage, + | ^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-68977.min.stderr b/src/test/ui/const-generics/issues/issue-68977.min.stderr new file mode 100644 index 00000000000..5b2137b244c --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-68977.min.stderr @@ -0,0 +1,18 @@ +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/issue-68977.rs:29:17 + | +LL | PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>; + | ^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `INT_BITS` + | + = help: it is currently only allowed to use either `INT_BITS` or `{ INT_BITS }` as generic constants + +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/issue-68977.rs:29:28 + | +LL | PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>; + | ^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `FRAC_BITS` + | + = help: it is currently only allowed to use either `FRAC_BITS` or `{ FRAC_BITS }` as generic constants + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/issues/issue-68977.rs b/src/test/ui/const-generics/issues/issue-68977.rs index 346ea3c2042..02e634efec3 100644 --- a/src/test/ui/const-generics/issues/issue-68977.rs +++ b/src/test/ui/const-generics/issues/issue-68977.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct PhantomU8<const X: u8>; @@ -25,11 +27,13 @@ fxp_storage_impls! { type FxpStorageHelper<const INT_BITS: u8, const FRAC_BITS: u8> = PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>; + //[min]~^ ERROR generic parameters must not be used inside of non trivial constant values + //[min]~| ERROR generic parameters must not be used inside of non trivial constant values struct Fxp<const INT_BITS: u8, const FRAC_BITS: u8> where FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage, - //~^ ERROR constant expression depends on a generic parameter + //[full]~^ ERROR constant expression depends on a generic parameter { storage: <FxpStorageHelper<INT_BITS, FRAC_BITS> as FxpStorage>::SInt, } diff --git a/src/test/ui/const-generics/issues/issue-68977.stderr b/src/test/ui/const-generics/issues/issue-68977.stderr deleted file mode 100644 index e1190d9026d..00000000000 --- a/src/test/ui/const-generics/issues/issue-68977.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-68977.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -error: constant expression depends on a generic parameter - --> $DIR/issue-68977.rs:31:44 - | -LL | FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage, - | ^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to previous error; 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-70125-1.rs b/src/test/ui/const-generics/issues/issue-70125-1.rs index 08a8309d431..04175089dc0 100644 --- a/src/test/ui/const-generics/issues/issue-70125-1.rs +++ b/src/test/ui/const-generics/issues/issue-70125-1.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] const L: usize = 4; diff --git a/src/test/ui/const-generics/issues/issue-70125-1.stderr b/src/test/ui/const-generics/issues/issue-70125-1.stderr deleted file mode 100644 index 8ad4b25ae5b..00000000000 --- a/src/test/ui/const-generics/issues/issue-70125-1.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-70125-1.rs:2:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-70125-2.rs b/src/test/ui/const-generics/issues/issue-70125-2.rs index fb7d4886a7c..ceefc2dcb32 100644 --- a/src/test/ui/const-generics/issues/issue-70125-2.rs +++ b/src/test/ui/const-generics/issues/issue-70125-2.rs @@ -1,7 +1,8 @@ // run-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] fn main() { <()>::foo(); diff --git a/src/test/ui/const-generics/issues/issue-70125-2.stderr b/src/test/ui/const-generics/issues/issue-70125-2.stderr deleted file mode 100644 index c1f9634810e..00000000000 --- a/src/test/ui/const-generics/issues/issue-70125-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-70125-2.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-70167.rs b/src/test/ui/const-generics/issues/issue-70167.rs index b53cec80071..04c76a4dcaf 100644 --- a/src/test/ui/const-generics/issues/issue-70167.rs +++ b/src/test/ui/const-generics/issues/issue-70167.rs @@ -1,7 +1,8 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] pub trait Trait<const N: usize>: From<<Self as Trait<N>>::Item> { type Item; diff --git a/src/test/ui/const-generics/issues/issue-70167.stderr b/src/test/ui/const-generics/issues/issue-70167.stderr deleted file mode 100644 index 5d647e933c4..00000000000 --- a/src/test/ui/const-generics/issues/issue-70167.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-70167.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-71169.stderr b/src/test/ui/const-generics/issues/issue-71169.full.stderr index 6d4cf4027c1..b87825d20ce 100644 --- a/src/test/ui/const-generics/issues/issue-71169.stderr +++ b/src/test/ui/const-generics/issues/issue-71169.full.stderr @@ -1,11 +1,11 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/issue-71169.rs:4:43 + --> $DIR/issue-71169.rs:6:43 | LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} | ^^^ the type must not depend on the parameter `LEN` error: constant expression depends on a generic parameter - --> $DIR/issue-71169.rs:8:14 + --> $DIR/issue-71169.rs:11:14 | LL | foo::<4, DATA>(); | ^^^^ diff --git a/src/test/ui/const-generics/issues/issue-71169.min.stderr b/src/test/ui/const-generics/issues/issue-71169.min.stderr new file mode 100644 index 00000000000..79d63443351 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-71169.min.stderr @@ -0,0 +1,18 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71169.rs:6:43 + | +LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} + | ^^^ the type must not depend on the parameter `LEN` + +error: `[u8; _]` is forbidden as the type of a const generic parameter + --> $DIR/issue-71169.rs:6:38 + | +LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} + | ^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/issues/issue-71169.rs b/src/test/ui/const-generics/issues/issue-71169.rs index 943a16cfcd6..7007ec222ca 100644 --- a/src/test/ui/const-generics/issues/issue-71169.rs +++ b/src/test/ui/const-generics/issues/issue-71169.rs @@ -1,10 +1,13 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} //~^ ERROR the type of const parameters must not +//[min]~^^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter fn main() { const DATA: [u8; 4] = *b"ABCD"; foo::<4, DATA>(); - //~^ ERROR constant expression depends on + //[full]~^ ERROR constant expression depends on } diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.full.stderr index fd4ebe3dead..453ef00e6dc 100644 --- a/src/test/ui/const-generics/issues/issue-71381.stderr +++ b/src/test/ui/const-generics/issues/issue-71381.full.stderr @@ -1,23 +1,23 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/issue-71381.rs:13:82 + --> $DIR/issue-71381.rs:15:82 | LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { | ^^^^ the type must not depend on the parameter `Args` error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/issue-71381.rs:22:40 + --> $DIR/issue-71381.rs:24:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71381.rs:13:61 + --> $DIR/issue-71381.rs:15:61 | LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71381.rs:22:19 + --> $DIR/issue-71381.rs:24:19 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/const-generics/issues/issue-71381.min.stderr b/src/test/ui/const-generics/issues/issue-71381.min.stderr new file mode 100644 index 00000000000..453ef00e6dc --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-71381.min.stderr @@ -0,0 +1,27 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71381.rs:15:82 + | +LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { + | ^^^^ the type must not depend on the parameter `Args` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71381.rs:24:40 + | +LL | const FN: unsafe extern "C" fn(Args), + | ^^^^ the type must not depend on the parameter `Args` + +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71381.rs:15:61 + | +LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71381.rs:24:19 + | +LL | const FN: unsafe extern "C" fn(Args), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/issues/issue-71381.rs b/src/test/ui/const-generics/issues/issue-71381.rs index 08f94823942..65d88e553b9 100644 --- a/src/test/ui/const-generics/issues/issue-71381.rs +++ b/src/test/ui/const-generics/issues/issue-71381.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Test(*const usize); diff --git a/src/test/ui/const-generics/issues/issue-71382.stderr b/src/test/ui/const-generics/issues/issue-71382.full.stderr index 1652b0bdfa8..3da85ee040d 100644 --- a/src/test/ui/const-generics/issues/issue-71382.stderr +++ b/src/test/ui/const-generics/issues/issue-71382.full.stderr @@ -1,5 +1,5 @@ error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71382.rs:15:23 + --> $DIR/issue-71382.rs:17:23 | LL | fn test<const FN: fn()>(&self) { | ^^^^ diff --git a/src/test/ui/const-generics/issues/issue-71382.min.stderr b/src/test/ui/const-generics/issues/issue-71382.min.stderr new file mode 100644 index 00000000000..3da85ee040d --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-71382.min.stderr @@ -0,0 +1,8 @@ +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71382.rs:17:23 + | +LL | fn test<const FN: fn()>(&self) { + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-71382.rs b/src/test/ui/const-generics/issues/issue-71382.rs index e0cf9812d95..12a7d08382a 100644 --- a/src/test/ui/const-generics/issues/issue-71382.rs +++ b/src/test/ui/const-generics/issues/issue-71382.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Test(); diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.full.stderr index e2c9f22361e..48d4bb361a1 100644 --- a/src/test/ui/const-generics/issues/issue-71611.stderr +++ b/src/test/ui/const-generics/issues/issue-71611.full.stderr @@ -1,11 +1,11 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/issue-71611.rs:4:31 + --> $DIR/issue-71611.rs:6:31 | LL | fn func<A, const F: fn(inner: A)>(outer: A) { | ^ the type must not depend on the parameter `A` error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71611.rs:4:21 + --> $DIR/issue-71611.rs:6:21 | LL | fn func<A, const F: fn(inner: A)>(outer: A) { | ^^^^^^^^^^^^ diff --git a/src/test/ui/const-generics/issues/issue-71611.min.stderr b/src/test/ui/const-generics/issues/issue-71611.min.stderr new file mode 100644 index 00000000000..48d4bb361a1 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-71611.min.stderr @@ -0,0 +1,15 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71611.rs:6:31 + | +LL | fn func<A, const F: fn(inner: A)>(outer: A) { + | ^ the type must not depend on the parameter `A` + +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71611.rs:6:21 + | +LL | fn func<A, const F: fn(inner: A)>(outer: A) { + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/issues/issue-71611.rs b/src/test/ui/const-generics/issues/issue-71611.rs index 06ff38dec66..9b8e8be6bc6 100644 --- a/src/test/ui/const-generics/issues/issue-71611.rs +++ b/src/test/ui/const-generics/issues/issue-71611.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] fn func<A, const F: fn(inner: A)>(outer: A) { //~^ ERROR: using function pointers as const generic parameters is forbidden diff --git a/src/test/ui/const-generics/issues/issue-72352.stderr b/src/test/ui/const-generics/issues/issue-72352.full.stderr index bc48da10393..51f94678467 100644 --- a/src/test/ui/const-generics/issues/issue-72352.stderr +++ b/src/test/ui/const-generics/issues/issue-72352.full.stderr @@ -1,5 +1,5 @@ error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-72352.rs:6:42 + --> $DIR/issue-72352.rs:8:42 | LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/const-generics/issues/issue-72352.min.stderr b/src/test/ui/const-generics/issues/issue-72352.min.stderr new file mode 100644 index 00000000000..51f94678467 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-72352.min.stderr @@ -0,0 +1,8 @@ +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-72352.rs:8:42 + | +LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize { + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-72352.rs b/src/test/ui/const-generics/issues/issue-72352.rs index e977af8deb7..1517f3dae4f 100644 --- a/src/test/ui/const-generics/issues/issue-72352.rs +++ b/src/test/ui/const-generics/issues/issue-72352.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] use std::ffi::{CStr, CString}; diff --git a/src/test/ui/const-generics/issues/issue-73491.min.stderr b/src/test/ui/const-generics/issues/issue-73491.min.stderr new file mode 100644 index 00000000000..5bf3671d38b --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-73491.min.stderr @@ -0,0 +1,11 @@ +error: `[u32; _]` is forbidden as the type of a const generic parameter + --> $DIR/issue-73491.rs:9:19 + | +LL | fn hoge<const IN: [u32; LEN]>() {} + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-73491.rs b/src/test/ui/const-generics/issues/issue-73491.rs index 05e1513bb75..4f6c44ad2cd 100644 --- a/src/test/ui/const-generics/issues/issue-73491.rs +++ b/src/test/ui/const-generics/issues/issue-73491.rs @@ -1,9 +1,12 @@ -// check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] const LEN: usize = 1024; fn hoge<const IN: [u32; LEN]>() {} +//[min]~^ ERROR `[u32; _]` is forbidden as the type of a const generic parameter fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-73508.full.stderr b/src/test/ui/const-generics/issues/issue-73508.full.stderr new file mode 100644 index 00000000000..0816bad35b2 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-73508.full.stderr @@ -0,0 +1,8 @@ +error: using raw pointers as const generic parameters is forbidden + --> $DIR/issue-73508.rs:6:33 + | +LL | pub const fn func_name<const X: *const u32>() {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-73508.min.stderr b/src/test/ui/const-generics/issues/issue-73508.min.stderr new file mode 100644 index 00000000000..0816bad35b2 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-73508.min.stderr @@ -0,0 +1,8 @@ +error: using raw pointers as const generic parameters is forbidden + --> $DIR/issue-73508.rs:6:33 + | +LL | pub const fn func_name<const X: *const u32>() {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-73508.rs b/src/test/ui/const-generics/issues/issue-73508.rs index ba2e2a38e74..21b87f7f901 100644 --- a/src/test/ui/const-generics/issues/issue-73508.rs +++ b/src/test/ui/const-generics/issues/issue-73508.rs @@ -1,4 +1,7 @@ -#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] pub const fn func_name<const X: *const u32>() {} //~^ ERROR using raw pointers diff --git a/src/test/ui/const-generics/issues/issue-73508.stderr b/src/test/ui/const-generics/issues/issue-73508.stderr deleted file mode 100644 index 23ad1818b6f..00000000000 --- a/src/test/ui/const-generics/issues/issue-73508.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-73508.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -error: using raw pointers as const generic parameters is forbidden - --> $DIR/issue-73508.rs:3:33 - | -LL | pub const fn func_name<const X: *const u32>() {} - | ^^^^^^^^^^ - -error: aborting due to previous error; 1 warning emitted - diff --git a/src/test/ui/const-generics/issues/issue-74101.min.stderr b/src/test/ui/const-generics/issues/issue-74101.min.stderr new file mode 100644 index 00000000000..8062faefbe6 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-74101.min.stderr @@ -0,0 +1,20 @@ +error: `[u8; _]` is forbidden as the type of a const generic parameter + --> $DIR/issue-74101.rs:7:18 + | +LL | fn test<const N: [u8; 1 + 2]>() {} + | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `[u8; _]` is forbidden as the type of a const generic parameter + --> $DIR/issue-74101.rs:10:21 + | +LL | struct Foo<const N: [u8; 1 + 2]>; + | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/issues/issue-74101.rs b/src/test/ui/const-generics/issues/issue-74101.rs index 2f427ef3a27..2a7d31ac8dd 100644 --- a/src/test/ui/const-generics/issues/issue-74101.rs +++ b/src/test/ui/const-generics/issues/issue-74101.rs @@ -1,9 +1,13 @@ -// check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] fn test<const N: [u8; 1 + 2]>() {} +//[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter struct Foo<const N: [u8; 1 + 2]>; +//[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-74255.min.stderr b/src/test/ui/const-generics/issues/issue-74255.min.stderr new file mode 100644 index 00000000000..86937d715c9 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-74255.min.stderr @@ -0,0 +1,11 @@ +error: `IceEnum` is forbidden as the type of a const generic parameter + --> $DIR/issue-74255.rs:15:31 + | +LL | fn ice_struct_fn<const I: IceEnum>() {} + | ^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-74255.rs b/src/test/ui/const-generics/issues/issue-74255.rs index 55ccf57dc99..b277c273461 100644 --- a/src/test/ui/const-generics/issues/issue-74255.rs +++ b/src/test/ui/const-generics/issues/issue-74255.rs @@ -1,6 +1,8 @@ -// check-pass -#![feature(const_generics)] -#![allow(dead_code, incomplete_features)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] #[derive(PartialEq, Eq)] enum IceEnum { @@ -11,6 +13,7 @@ struct IceStruct; impl IceStruct { fn ice_struct_fn<const I: IceEnum>() {} + //[min]~^ ERROR `IceEnum` is forbidden as the type of a const generic parameter } fn main() { diff --git a/src/test/ui/const-generics/issues/issue-75047.min.stderr b/src/test/ui/const-generics/issues/issue-75047.min.stderr new file mode 100644 index 00000000000..edc54b082db --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-75047.min.stderr @@ -0,0 +1,11 @@ +error: `[u8; _]` is forbidden as the type of a const generic parameter + --> $DIR/issue-75047.rs:15:21 + | +LL | struct Foo<const N: [u8; Bar::<u32>::value()]>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-75047.rs b/src/test/ui/const-generics/issues/issue-75047.rs index 5d068d851c1..7bab7cdd098 100644 --- a/src/test/ui/const-generics/issues/issue-75047.rs +++ b/src/test/ui/const-generics/issues/issue-75047.rs @@ -1,6 +1,8 @@ -// check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Bar<T>(T); @@ -11,5 +13,6 @@ impl<T> Bar<T> { } struct Foo<const N: [u8; Bar::<u32>::value()]>; +//[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter fn main() {} diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs index c22e61d0ce3..28f80702dcf 100644 --- a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs +++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs @@ -1,7 +1,8 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait T<const A: usize> { fn f(); diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr b/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr deleted file mode 100644 index 931701b64b4..00000000000 --- a/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue70273-assoc-fn.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/std/const-generics-range.min.stderr b/src/test/ui/const-generics/std/const-generics-range.min.stderr new file mode 100644 index 00000000000..a71e7442021 --- /dev/null +++ b/src/test/ui/const-generics/std/const-generics-range.min.stderr @@ -0,0 +1,56 @@ +error: `std::ops::Range<usize>` is forbidden as the type of a const generic parameter + --> $DIR/const-generics-range.rs:8:24 + | +LL | struct _Range<const R: std::ops::Range<usize>>; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `std::ops::RangeFrom<usize>` is forbidden as the type of a const generic parameter + --> $DIR/const-generics-range.rs:13:28 + | +LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `std::ops::RangeFull` is forbidden as the type of a const generic parameter + --> $DIR/const-generics-range.rs:18:28 + | +LL | struct _RangeFull<const R: std::ops::RangeFull>; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `std::ops::RangeInclusive<usize>` is forbidden as the type of a const generic parameter + --> $DIR/const-generics-range.rs:24:33 + | +LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `std::ops::RangeTo<usize>` is forbidden as the type of a const generic parameter + --> $DIR/const-generics-range.rs:29:26 + | +LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `std::ops::RangeToInclusive<usize>` is forbidden as the type of a const generic parameter + --> $DIR/const-generics-range.rs:34:35 + | +LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/const-generics/std/const-generics-range.rs b/src/test/ui/const-generics/std/const-generics-range.rs index 6d56fe0d7b8..c04f4a3acfb 100644 --- a/src/test/ui/const-generics/std/const-generics-range.rs +++ b/src/test/ui/const-generics/std/const-generics-range.rs @@ -1,30 +1,38 @@ -// check-pass -#![allow(incomplete_features)] -#![feature(const_generics)] +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] // `Range` should be usable within const generics: struct _Range<const R: std::ops::Range<usize>>; +//[min]~^ ERROR `std::ops::Range<usize>` is forbidden const RANGE : _Range<{ 0 .. 1000 }> = _Range; // `RangeFrom` should be usable within const generics: struct _RangeFrom<const R: std::ops::RangeFrom<usize>>; +//[min]~^ ERROR `std::ops::RangeFrom<usize>` is forbidden const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom; // `RangeFull` should be usable within const generics: struct _RangeFull<const R: std::ops::RangeFull>; +//[min]~^ ERROR `std::ops::RangeFull` is forbidden const RANGE_FULL : _RangeFull<{ .. }> = _RangeFull; // Regression test for #70155 // `RangeInclusive` should be usable within const generics: struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>; +//[min]~^ ERROR `std::ops::RangeInclusive<usize>` is forbidden const RANGE_INCLUSIVE : _RangeInclusive<{ 0 ..= 999 }> = _RangeInclusive; // `RangeTo` should be usable within const generics: struct _RangeTo<const R: std::ops::RangeTo<usize>>; +//[min]~^ ERROR `std::ops::RangeTo<usize>` is forbidden const RANGE_TO : _RangeTo<{ .. 1000 }> = _RangeTo; // `RangeToInclusive` should be usable within const generics: struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>; +//[min]~^ ERROR `std::ops::RangeToInclusive<usize>` is forbidden const RANGE_TO_INCLUSIVE : _RangeToInclusive<{ ..= 999 }> = _RangeToInclusive; pub fn main() {} diff --git a/src/test/ui/const-generics/type-after-const-ok.min.stderr b/src/test/ui/const-generics/type-after-const-ok.min.stderr new file mode 100644 index 00000000000..67a44d2c5b4 --- /dev/null +++ b/src/test/ui/const-generics/type-after-const-ok.min.stderr @@ -0,0 +1,8 @@ +error: type parameters must be declared prior to const parameters + --> $DIR/type-after-const-ok.rs:9:26 + | +LL | struct A<const N: usize, T>(T); + | -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/type-after-const-ok.rs b/src/test/ui/const-generics/type-after-const-ok.rs index fc977d6617c..69227cdf19c 100644 --- a/src/test/ui/const-generics/type-after-const-ok.rs +++ b/src/test/ui/const-generics/type-after-const-ok.rs @@ -1,10 +1,12 @@ -// run-pass +// [full] run-pass +// revisions: full min // Verifies that having generic parameters after constants is permitted - -#![feature(const_generics)] -#![allow(incomplete_features)] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] #[allow(dead_code)] struct A<const N: usize, T>(T); +//[min]~^ ERROR type parameters must be declared prior to const parameters fn main() {} diff --git a/src/test/ui/const-generics/type-dependent/issue-61936.rs b/src/test/ui/const-generics/type-dependent/issue-61936.rs index a7a923c6a59..1d42afa3f84 100644 --- a/src/test/ui/const-generics/type-dependent/issue-61936.rs +++ b/src/test/ui/const-generics/type-dependent/issue-61936.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait SliceExt<T: Clone> { fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>; diff --git a/src/test/ui/const-generics/type-dependent/issue-63695.rs b/src/test/ui/const-generics/type-dependent/issue-63695.rs index f3c2e177594..465b66b09ce 100644 --- a/src/test/ui/const-generics/type-dependent/issue-63695.rs +++ b/src/test/ui/const-generics/type-dependent/issue-63695.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait T { fn test<const A: i32>(&self) -> i32 { A } diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs index a3d05959198..3d4910e9e4b 100644 --- a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs +++ b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs @@ -1,6 +1,8 @@ // check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct X; diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs index c53a149fa8d..0868d309b33 100644 --- a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs +++ b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs @@ -1,6 +1,8 @@ // check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct A<const N: usize>; diff --git a/src/test/ui/const-generics/type-dependent/issue-69816.rs b/src/test/ui/const-generics/type-dependent/issue-69816.rs index cbe86cef323..4a374dc1db6 100644 --- a/src/test/ui/const-generics/type-dependent/issue-69816.rs +++ b/src/test/ui/const-generics/type-dependent/issue-69816.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait IterExt: Sized + Iterator { fn default_for_size<const N: usize>(self) -> [Self::Item; N] diff --git a/src/test/ui/const-generics/type-dependent/issue-70217.rs b/src/test/ui/const-generics/type-dependent/issue-70217.rs index caa611cbd79..ba5a42e47e9 100644 --- a/src/test/ui/const-generics/type-dependent/issue-70217.rs +++ b/src/test/ui/const-generics/type-dependent/issue-70217.rs @@ -1,6 +1,9 @@ // check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Struct<const N: usize>; diff --git a/src/test/ui/const-generics/type-dependent/issue-70507.rs b/src/test/ui/const-generics/type-dependent/issue-70507.rs index 6fcf4116d43..234c09e04ae 100644 --- a/src/test/ui/const-generics/type-dependent/issue-70507.rs +++ b/src/test/ui/const-generics/type-dependent/issue-70507.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait ConstChunksExactTrait<T> { fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>; diff --git a/src/test/ui/const-generics/type-dependent/issue-70586.rs b/src/test/ui/const-generics/type-dependent/issue-70586.rs index 5a0888506eb..fd52373cee2 100644 --- a/src/test/ui/const-generics/type-dependent/issue-70586.rs +++ b/src/test/ui/const-generics/type-dependent/issue-70586.rs @@ -1,6 +1,8 @@ // check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] use std::marker::PhantomData; diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr new file mode 100644 index 00000000000..8656239605d --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -0,0 +1,20 @@ +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/issue-71348.rs:11:24 + | +LL | trait Get<'a, const N: &'static str> { + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/issue-71348.rs:19:25 + | +LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.rs b/src/test/ui/const-generics/type-dependent/issue-71348.rs index ec22dcdf60b..772e179746d 100644 --- a/src/test/ui/const-generics/type-dependent/issue-71348.rs +++ b/src/test/ui/const-generics/type-dependent/issue-71348.rs @@ -1,12 +1,15 @@ -// run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// [full] run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Foo { i: i32, } trait Get<'a, const N: &'static str> { + //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter type Target: 'a; fn get(&'a self) -> &'a Self::Target; @@ -14,6 +17,7 @@ trait Get<'a, const N: &'static str> { impl Foo { fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target + //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter where Self: Get<'a, N>, { diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr new file mode 100644 index 00000000000..da1d3270b7c --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr @@ -0,0 +1,8 @@ +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71382.rs:17:23 + | +LL | fn test<const FN: fn() -> u8>(&self) -> u8 { + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr new file mode 100644 index 00000000000..da1d3270b7c --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr @@ -0,0 +1,8 @@ +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71382.rs:17:23 + | +LL | fn test<const FN: fn() -> u8>(&self) -> u8 { + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.rs b/src/test/ui/const-generics/type-dependent/issue-71382.rs index 05abd488816..497fd1381de 100644 --- a/src/test/ui/const-generics/type-dependent/issue-71382.rs +++ b/src/test/ui/const-generics/type-dependent/issue-71382.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct Test; diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.stderr deleted file mode 100644 index f441b71031e..00000000000 --- a/src/test/ui/const-generics/type-dependent/issue-71382.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-71382.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -error: using function pointers as const generic parameters is forbidden - --> $DIR/issue-71382.rs:15:23 - | -LL | fn test<const FN: fn() -> u8>(&self) -> u8 { - | ^^^^^^^^^^ - -error: aborting due to previous error; 1 warning emitted - diff --git a/src/test/ui/const-generics/type-dependent/issue-71805.rs b/src/test/ui/const-generics/type-dependent/issue-71805.rs index 6823d780aef..2aaf12cea4f 100644 --- a/src/test/ui/const-generics/type-dependent/issue-71805.rs +++ b/src/test/ui/const-generics/type-dependent/issue-71805.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] use std::mem::MaybeUninit; diff --git a/src/test/ui/const-generics/type-dependent/issue-73730.rs b/src/test/ui/const-generics/type-dependent/issue-73730.rs index d90cc50ddc4..3e53190ee48 100644 --- a/src/test/ui/const-generics/type-dependent/issue-73730.rs +++ b/src/test/ui/const-generics/type-dependent/issue-73730.rs @@ -1,6 +1,8 @@ // check-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] trait Foo<'a, A>: Iterator<Item=A> { fn bar<const N: usize>(&mut self) -> *const [A; N]; diff --git a/src/test/ui/const-generics/type-dependent/non-local.rs b/src/test/ui/const-generics/type-dependent/non-local.rs index e6f3eb075f1..747664a0962 100644 --- a/src/test/ui/const-generics/type-dependent/non-local.rs +++ b/src/test/ui/const-generics/type-dependent/non-local.rs @@ -1,7 +1,9 @@ // aux-build:type_dependent_lib.rs // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] extern crate type_dependent_lib; diff --git a/src/test/ui/const-generics/type-dependent/qpath.rs b/src/test/ui/const-generics/type-dependent/qpath.rs index f3f98e5faf5..ec23ff1d221 100644 --- a/src/test/ui/const-generics/type-dependent/qpath.rs +++ b/src/test/ui/const-generics/type-dependent/qpath.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct A; impl A { diff --git a/src/test/ui/const-generics/type-dependent/simple.rs b/src/test/ui/const-generics/type-dependent/simple.rs index cc7c50d8fd8..70af6550923 100644 --- a/src/test/ui/const-generics/type-dependent/simple.rs +++ b/src/test/ui/const-generics/type-dependent/simple.rs @@ -1,6 +1,8 @@ // run-pass -#![feature(const_generics)] -#![allow(incomplete_features)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct R; diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr new file mode 100644 index 00000000000..a530e63449d --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:12:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +help: change the type of the numeric literal from `u16` to `u8` + | +LL | assert_eq!(R.method::<1u8>(), 1); + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr new file mode 100644 index 00000000000..a530e63449d --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:12:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +help: change the type of the numeric literal from `u16` to `u8` + | +LL | assert_eq!(R.method::<1u8>(), 1); + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.rs b/src/test/ui/const-generics/type-dependent/type-mismatch.rs index 0c71f338bd2..67d80973f03 100644 --- a/src/test/ui/const-generics/type-dependent/type-mismatch.rs +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] struct R; diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.stderr deleted file mode 100644 index 5bb7c5b0ea9..00000000000 --- a/src/test/ui/const-generics/type-dependent/type-mismatch.stderr +++ /dev/null @@ -1,23 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-mismatch.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -error[E0308]: mismatched types - --> $DIR/type-mismatch.rs:10:27 - | -LL | assert_eq!(R.method::<1u16>(), 1); - | ^^^^ expected `u8`, found `u16` - | -help: change the type of the numeric literal from `u16` to `u8` - | -LL | assert_eq!(R.method::<1u8>(), 1); - | ^^^ - -error: aborting due to previous error; 1 warning emitted - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/types-mismatch-const-args.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr index 49530c9d240..265e9ee618b 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr @@ -1,14 +1,5 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/types-mismatch-const-args.rs:1:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - error[E0308]: mismatched types - --> $DIR/types-mismatch-const-args.rs:13:41 + --> $DIR/types-mismatch-const-args.rs:15:41 | LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32` @@ -17,7 +8,7 @@ LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data found type `4_u32` error[E0308]: mismatched types - --> $DIR/types-mismatch-const-args.rs:15:41 + --> $DIR/types-mismatch-const-args.rs:17:41 | LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32` @@ -27,6 +18,6 @@ LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data = note: expected struct `A<'a, u16, {2u32}, {3u32}>` found struct `A<'b, u32, {2u32}, {3u32}>` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr new file mode 100644 index 00000000000..27277f0c0be --- /dev/null +++ b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/types-mismatch-const-args.rs:15:41 + | +LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData }; + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32` + | | + | expected due to this + | + = note: expected struct `A<'_, _, 2_u32, _>` + found struct `A<'_, _, 4_u32, _>` + +error[E0308]: mismatched types + --> $DIR/types-mismatch-const-args.rs:17:41 + | +LL | let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32` + | | + | expected due to this + | + = note: expected struct `A<'a, u16, _, _>` + found struct `A<'b, u32, _, _>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/types-mismatch-const-args.rs b/src/test/ui/const-generics/types-mismatch-const-args.rs index bf517c11262..34b85304cc4 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.rs +++ b/src/test/ui/const-generics/types-mismatch-const-args.rs @@ -1,5 +1,7 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] // tests the diagnostic output of type mismatches for types that have const generics arguments. diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs index 7473718351e..45afbdc9ab1 100644 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs @@ -1,7 +1,8 @@ // run-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] use std::fmt; diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr deleted file mode 100644 index f41628d5d8e..00000000000 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/uninferred-consts-during-codegen-1.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs index 8b95a010473..65ae05e1198 100644 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs @@ -1,7 +1,8 @@ // run-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] use std::fmt; diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr deleted file mode 100644 index f1703bc3a2f..00000000000 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/uninferred-consts-during-codegen-2.rs:3:12 - | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information - -warning: 1 warning emitted - diff --git a/src/test/ui/consts/cow-is-borrowed.rs b/src/test/ui/consts/cow-is-borrowed.rs new file mode 100644 index 00000000000..adebe20f5a2 --- /dev/null +++ b/src/test/ui/consts/cow-is-borrowed.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(cow_is_borrowed)] + +use std::borrow::Cow; + +fn main() { + const COW: Cow<str> = Cow::Borrowed("moo"); + + const IS_BORROWED: bool = COW.is_borrowed(); + assert!(IS_BORROWED); + + const IS_OWNED: bool = COW.is_owned(); + assert!(!IS_OWNED); +} diff --git a/src/test/ui/consts/std/net/ipv4.rs b/src/test/ui/consts/std/net/ipv4.rs new file mode 100644 index 00000000000..8c676999ae7 --- /dev/null +++ b/src/test/ui/consts/std/net/ipv4.rs @@ -0,0 +1,58 @@ +// run-pass + +#![feature(ip)] +#![feature(const_ipv4)] + +use std::net::{Ipv4Addr, Ipv6Addr}; + +fn main() { + const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); + assert_eq!(IP_ADDRESS, Ipv4Addr::LOCALHOST); + + const OCTETS: [u8; 4] = IP_ADDRESS.octets(); + assert_eq!(OCTETS, [127, 0, 0, 1]); + + const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified(); + assert!(!IS_UNSPECIFIED); + + const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback(); + assert!(IS_LOOPBACK); + + const IS_PRIVATE : bool = IP_ADDRESS.is_private(); + assert!(!IS_PRIVATE); + + const IS_LINK_LOCAL : bool = IP_ADDRESS.is_link_local(); + assert!(!IS_LINK_LOCAL); + + const IS_GLOBAL : bool = IP_ADDRESS.is_global(); + assert!(!IS_GLOBAL); + + const IS_SHARED : bool = IP_ADDRESS.is_shared(); + assert!(!IS_SHARED); + + const IS_IETF_PROTOCOL_ASSIGNMENT : bool = IP_ADDRESS.is_ietf_protocol_assignment(); + assert!(!IS_IETF_PROTOCOL_ASSIGNMENT); + + const IS_BENCHMARKING : bool = IP_ADDRESS.is_benchmarking(); + assert!(!IS_BENCHMARKING); + + const IS_RESERVED : bool = IP_ADDRESS.is_reserved(); + assert!(!IS_RESERVED); + + const IS_MULTICAST : bool = IP_ADDRESS.is_multicast(); + assert!(!IS_MULTICAST); + + const IS_BROADCAST : bool = IP_ADDRESS.is_broadcast(); + assert!(!IS_BROADCAST); + + const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation(); + assert!(!IS_DOCUMENTATION); + + const IP_V6_COMPATIBLE : Ipv6Addr = IP_ADDRESS.to_ipv6_compatible(); + assert_eq!(IP_V6_COMPATIBLE, + Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1])); + + const IP_V6_MAPPED : Ipv6Addr = IP_ADDRESS.to_ipv6_mapped(); + assert_eq!(IP_V6_MAPPED, + Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1])); +} diff --git a/src/test/ui/consts/std/net/ipv6.rs b/src/test/ui/consts/std/net/ipv6.rs new file mode 100644 index 00000000000..e3841c38c22 --- /dev/null +++ b/src/test/ui/consts/std/net/ipv6.rs @@ -0,0 +1,53 @@ +// run-pass + +#![feature(ip)] +#![feature(const_ipv6)] + +use std::net::{Ipv4Addr, Ipv6Addr, Ipv6MulticastScope}; + +fn main() { + const IP_ADDRESS : Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); + assert_eq!(IP_ADDRESS, Ipv6Addr::LOCALHOST); + + const SEGMENTS : [u16; 8] = IP_ADDRESS.segments(); + assert_eq!(SEGMENTS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 1]); + + const OCTETS : [u8; 16] = IP_ADDRESS.octets(); + assert_eq!(OCTETS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 0 ,0 ,0 ,0 ,0 ,0 ,0, 0, 1]); + + const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified(); + assert!(!IS_UNSPECIFIED); + + const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback(); + assert!(IS_LOOPBACK); + + const IS_GLOBAL : bool = IP_ADDRESS.is_global(); + assert!(!IS_GLOBAL); + + const IS_UNIQUE_LOCAL : bool = IP_ADDRESS.is_unique_local(); + assert!(!IS_UNIQUE_LOCAL); + + const IS_UNICAST_LINK_LOCAL_STRICT : bool = IP_ADDRESS.is_unicast_link_local_strict(); + assert!(!IS_UNICAST_LINK_LOCAL_STRICT); + + const IS_UNICAST_LINK_LOCAL : bool = IP_ADDRESS.is_unicast_link_local(); + assert!(!IS_UNICAST_LINK_LOCAL); + + const IS_UNICAST_SITE_LOCAL : bool = IP_ADDRESS.is_unicast_site_local(); + assert!(!IS_UNICAST_SITE_LOCAL); + + const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation(); + assert!(!IS_DOCUMENTATION); + + const IS_UNICAST_GLOBAL : bool = IP_ADDRESS.is_unicast_global(); + assert!(!IS_UNICAST_GLOBAL); + + const MULTICAST_SCOPE : Option<Ipv6MulticastScope> = IP_ADDRESS.multicast_scope(); + assert_eq!(MULTICAST_SCOPE, None); + + const IS_MULTICAST : bool = IP_ADDRESS.is_multicast(); + assert!(!IS_MULTICAST); + + const IP_V4 : Option<Ipv4Addr> = IP_ADDRESS.to_ipv4(); + assert_eq!(IP_V4.unwrap(), Ipv4Addr::new(0, 0, 0, 1)); +} diff --git a/src/test/ui/error-codes/E0070.stderr b/src/test/ui/error-codes/E0070.stderr index d809bb18dee..e24d498e352 100644 --- a/src/test/ui/error-codes/E0070.stderr +++ b/src/test/ui/error-codes/E0070.stderr @@ -14,12 +14,6 @@ LL | 1 = 3; | | | cannot assign to this expression -error[E0308]: mismatched types - --> $DIR/E0070.rs:8:25 - | -LL | some_other_func() = 4; - | ^ expected `()`, found integer - error[E0070]: invalid left-hand side of assignment --> $DIR/E0070.rs:8:23 | @@ -28,6 +22,12 @@ LL | some_other_func() = 4; | | | cannot assign to this expression +error[E0308]: mismatched types + --> $DIR/E0070.rs:8:25 + | +LL | some_other_func() = 4; + | ^ expected `()`, found integer + error: aborting due to 4 previous errors Some errors have detailed explanations: E0070, E0308. diff --git a/src/test/ui/fmt/incorrect-separator.rs b/src/test/ui/fmt/incorrect-separator.rs new file mode 100644 index 00000000000..b8d2e4a3473 --- /dev/null +++ b/src/test/ui/fmt/incorrect-separator.rs @@ -0,0 +1,29 @@ +// Allows to track issue #75492: +// https://github.com/rust-lang/rust/issues/75492 + +use std::iter; + +fn main() { + format!("A number: {}". iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `.` + + // Other kind of types are also checked: + + format!("A number: {}" / iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `/` + + format!("A number: {}"; iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `;` + + // Note: this character is an COMBINING COMMA BELOW unicode char + format!("A number: {}" ̦ iter::once(42).next().unwrap()); + //~^ ERROR expected `,`, found `iter` + //~^^ ERROR unknown start of token: \u{326} + + // Here recovery is tested. + // If the `compile_error!` is emitted, then the parser is able to recover + // from the incorrect first separator. + format!("{}". compile_error!("fail")); + //~^ ERROR expected `,`, found `.` + //~^^ ERROR fail +} diff --git a/src/test/ui/fmt/incorrect-separator.stderr b/src/test/ui/fmt/incorrect-separator.stderr new file mode 100644 index 00000000000..5a3e5515bb9 --- /dev/null +++ b/src/test/ui/fmt/incorrect-separator.stderr @@ -0,0 +1,44 @@ +error: unknown start of token: \u{326} + --> $DIR/incorrect-separator.rs:19:28 + | +LL | format!("A number: {}" ̦ iter::once(42).next().unwrap()); + | ^ + +error: expected `,`, found `.` + --> $DIR/incorrect-separator.rs:7:27 + | +LL | format!("A number: {}". iter::once(42).next().unwrap()); + | ^ expected `,` + +error: expected `,`, found `/` + --> $DIR/incorrect-separator.rs:12:28 + | +LL | format!("A number: {}" / iter::once(42).next().unwrap()); + | ^ expected `,` + +error: expected `,`, found `;` + --> $DIR/incorrect-separator.rs:15:27 + | +LL | format!("A number: {}"; iter::once(42).next().unwrap()); + | ^ expected `,` + +error: expected `,`, found `iter` + --> $DIR/incorrect-separator.rs:19:30 + | +LL | format!("A number: {}" ̦ iter::once(42).next().unwrap()); + | ^^^^ expected `,` + +error: expected `,`, found `.` + --> $DIR/incorrect-separator.rs:26:17 + | +LL | format!("{}". compile_error!("fail")); + | ^ expected `,` + +error: fail + --> $DIR/incorrect-separator.rs:26:19 + | +LL | format!("{}". compile_error!("fail")); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/issues/issue-13407.stderr b/src/test/ui/issues/issue-13407.stderr index f30b6cdeaf0..5352066bf77 100644 --- a/src/test/ui/issues/issue-13407.stderr +++ b/src/test/ui/issues/issue-13407.stderr @@ -10,12 +10,6 @@ note: the unit struct `C` is defined here LL | struct C; | ^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/issue-13407.rs:6:12 - | -LL | A::C = 1; - | ^ expected struct `A::C`, found integer - error[E0070]: invalid left-hand side of assignment --> $DIR/issue-13407.rs:6:10 | @@ -24,6 +18,12 @@ LL | A::C = 1; | | | cannot assign to this expression +error[E0308]: mismatched types + --> $DIR/issue-13407.rs:6:12 + | +LL | A::C = 1; + | ^ expected struct `A::C`, found integer + error: aborting due to 3 previous errors Some errors have detailed explanations: E0070, E0308, E0603. diff --git a/src/test/ui/macros/duplicate-builtin.rs b/src/test/ui/macros/duplicate-builtin.rs new file mode 100644 index 00000000000..35f0f429059 --- /dev/null +++ b/src/test/ui/macros/duplicate-builtin.rs @@ -0,0 +1,17 @@ +// compile-flags:--crate-type lib +#![feature(decl_macro)] +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +pub macro test($item:item) { +//~^ NOTE previously defined + /* compiler built-in */ +} + +mod inner { + #[rustc_builtin_macro] + pub macro test($item:item) { + //~^ ERROR attempted to define built-in macro more than once [E0773] + /* compiler built-in */ + } +} diff --git a/src/test/ui/macros/duplicate-builtin.stderr b/src/test/ui/macros/duplicate-builtin.stderr new file mode 100644 index 00000000000..58accea27bb --- /dev/null +++ b/src/test/ui/macros/duplicate-builtin.stderr @@ -0,0 +1,21 @@ +error[E0773]: attempted to define built-in macro more than once + --> $DIR/duplicate-builtin.rs:13:5 + | +LL | / pub macro test($item:item) { +LL | | +LL | | /* compiler built-in */ +LL | | } + | |_____^ + | +note: previously defined here + --> $DIR/duplicate-builtin.rs:6:1 + | +LL | / pub macro test($item:item) { +LL | | +LL | | /* compiler built-in */ +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0773`. diff --git a/src/test/ui/macros/missing-comma.rs b/src/test/ui/macros/missing-comma.rs index 2002fed6c93..92f8a779505 100644 --- a/src/test/ui/macros/missing-comma.rs +++ b/src/test/ui/macros/missing-comma.rs @@ -17,7 +17,7 @@ macro_rules! check { fn main() { println!("{}" a); - //~^ ERROR expected token: `,` + //~^ ERROR expected `,`, found `a` foo!(a b); //~^ ERROR no rules expected the token `b` foo!(a, b, c, d e); diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index f96848f8239..6da92bdea19 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -1,4 +1,4 @@ -error: expected token: `,` +error: expected `,`, found `a` --> $DIR/missing-comma.rs:19:19 | LL | println!("{}" a); diff --git a/src/test/ui/macros/unknown-builtin.rs b/src/test/ui/macros/unknown-builtin.rs index a96b99ae4ff..16f9139e647 100644 --- a/src/test/ui/macros/unknown-builtin.rs +++ b/src/test/ui/macros/unknown-builtin.rs @@ -1,4 +1,4 @@ -// error-pattern: cannot find a built-in macro with name `line` +// error-pattern: attempted to define built-in macro more than once #![feature(rustc_attrs)] @@ -6,7 +6,7 @@ macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown` #[rustc_builtin_macro] -macro_rules! line { () => () } +macro_rules! line { () => () } //~ NOTE previously defined here fn main() { line!(); diff --git a/src/test/ui/macros/unknown-builtin.stderr b/src/test/ui/macros/unknown-builtin.stderr index 4b650b2c475..7b04e05293e 100644 --- a/src/test/ui/macros/unknown-builtin.stderr +++ b/src/test/ui/macros/unknown-builtin.stderr @@ -4,7 +4,7 @@ error: cannot find a built-in macro with name `unknown` LL | macro_rules! unknown { () => () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find a built-in macro with name `line` +error[E0773]: attempted to define built-in macro more than once --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | LL | / macro_rules! line { @@ -13,6 +13,13 @@ LL | | /* compiler built-in */ LL | | }; LL | | } | |_____^ + | +note: previously defined here + --> $DIR/unknown-builtin.rs:9:1 + | +LL | macro_rules! line { () => () } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0773`. diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.rs b/src/test/ui/parser/shebang/shebang-doc-comment.rs index 7dbb9eebc75..72866753e0e 100644 --- a/src/test/ui/parser/shebang/shebang-doc-comment.rs +++ b/src/test/ui/parser/shebang/shebang-doc-comment.rs @@ -1,6 +1,3 @@ #!///bin/bash [allow(unused_variables)] -//~^^ ERROR expected `[`, found doc comment - -// Doc comment is misinterpreted as a whitespace (regular comment) during shebang detection. -// Even if it wasn't, it would still result in an error, just a different one. +//~^ ERROR expected item, found `[` diff --git a/src/test/ui/parser/shebang/shebang-doc-comment.stderr b/src/test/ui/parser/shebang/shebang-doc-comment.stderr index f524f556837..2227d45ec5a 100644 --- a/src/test/ui/parser/shebang/shebang-doc-comment.stderr +++ b/src/test/ui/parser/shebang/shebang-doc-comment.stderr @@ -1,8 +1,8 @@ -error: expected `[`, found doc comment `///bin/bash` - --> $DIR/shebang-doc-comment.rs:1:3 +error: expected item, found `[` + --> $DIR/shebang-doc-comment.rs:2:1 | -LL | #!///bin/bash - | ^^^^^^^^^^^ expected `[` +LL | [allow(unused_variables)] + | ^ expected item error: aborting due to previous error diff --git a/src/test/ui/parser/unicode-quote-chars.rs b/src/test/ui/parser/unicode-quote-chars.rs index 1812dad81af..eeaea3628bb 100644 --- a/src/test/ui/parser/unicode-quote-chars.rs +++ b/src/test/ui/parser/unicode-quote-chars.rs @@ -6,5 +6,5 @@ fn main() { //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not //~^^^ ERROR unknown start of token: \u{201d} //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not - //~^^^^^ ERROR expected token: `,` + //~^^^^^ ERROR expected `,`, found `world` } diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr index 4b0cb96ed21..d9ec92b3f8a 100644 --- a/src/test/ui/parser/unicode-quote-chars.stderr +++ b/src/test/ui/parser/unicode-quote-chars.stderr @@ -20,7 +20,7 @@ help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quot LL | println!(“hello world"); | ^ -error: expected token: `,` +error: expected `,`, found `world` --> $DIR/unicode-quote-chars.rs:4:21 | LL | println!(“hello world”); diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 2aa0824f301..6b42c0e0848 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,4 +1,4 @@ -thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/thir/pattern/_match.rs:LL:CC +thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', compiler/rustc_mir_build/src/thir/pattern/_match.rs:LL:CC note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.rs b/src/test/ui/proc-macro/issue-75930-derive-cfg.rs new file mode 100644 index 00000000000..e0f248c67e8 --- /dev/null +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.rs @@ -0,0 +1,30 @@ +// check-pass +// compile-flags: -Z span-debug +// aux-build:test-macros.rs + +// Regression test for issue #75930 +// Tests that we cfg-strip all targets before invoking +// a derive macro + +#[macro_use] +extern crate test_macros; + +#[derive(Print)] +struct Foo<#[cfg(FALSE)] A, B> { + #[cfg(FALSE)] first: String, + second: bool, + third: [u8; { + #[cfg(FALSE)] struct Bar; + #[cfg(not(FALSE))] struct Inner; + #[cfg(FALSE)] let a = 25; + match true { + #[cfg(FALSE)] true => {}, + false => {}, + _ => {} + }; + 0 + }], + fourth: B +} + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout new file mode 100644 index 00000000000..0371133a3f7 --- /dev/null +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -0,0 +1,221 @@ +PRINT-DERIVE INPUT (DISPLAY): struct Foo < B > +{ + second : bool, third : + [u8 ; + { + #[cfg(not(FALSE))] struct Inner ; match true + { false => { } _ => { } } ; 0 + }], fourth : B, +} +PRINT-DERIVE INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "Foo", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: '<', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "B", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Ident { + ident: "second", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ':', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "bool", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "third", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ':', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "u8", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "cfg", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "not", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "FALSE", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "struct", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "Inner", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "match", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "true", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Ident { + ident: "false", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: '=', + spacing: Joint, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "_", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: '=', + spacing: Joint, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ';', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Literal { + kind: Integer, + symbol: "0", + suffix: None, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "fourth", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ':', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Ident { + ident: "B", + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + Punct { + ch: ',', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:1:1: 1:1 (#0), + }, +] diff --git a/src/test/ui/proc-macro/load-panic-backtrace.rs b/src/test/ui/proc-macro/load-panic-backtrace.rs new file mode 100644 index 00000000000..90fe109abb8 --- /dev/null +++ b/src/test/ui/proc-macro/load-panic-backtrace.rs @@ -0,0 +1,21 @@ +// aux-build:test-macros.rs +// compile-flags: -Z proc-macro-backtrace +// rustc-env:RUST_BACKTRACE=0 + +// FIXME https://github.com/rust-lang/rust/issues/59998 +// normalize-stderr-test "thread '.*' panicked " -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" + +#[macro_use] +extern crate test_macros; + +#[derive(Panic)] +//~^ ERROR: proc-macro derive panicked +struct Foo; + +fn main() {} diff --git a/src/test/ui/proc-macro/load-panic-backtrace.stderr b/src/test/ui/proc-macro/load-panic-backtrace.stderr new file mode 100644 index 00000000000..63378b5735a --- /dev/null +++ b/src/test/ui/proc-macro/load-panic-backtrace.stderr @@ -0,0 +1,11 @@ +at 'panic-derive', $DIR/auxiliary/test-macros.rs:43:5 +error: proc-macro derive panicked + --> $DIR/load-panic-backtrace.rs:17:10 + | +LL | #[derive(Panic)] + | ^^^^^ + | + = help: message: panic-derive + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index 7f343d1a853..3372495d0fe 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -568,10 +568,12 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:56:8 | LL | if x = let 0 = 0 {} - | ^^^^^^^^^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `x == let 0 = 0` + | ^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == let 0 = 0 {} + | ^^ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:59:8 @@ -754,10 +756,12 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:120:11 | LL | while x = let 0 = 0 {} - | ^^^^^^^^^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `x == let 0 = 0` + | ^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | while x == let 0 = 0 {} + | ^^ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:123:11 diff --git a/src/test/ui/suggestions/if-let-typo.rs b/src/test/ui/suggestions/if-let-typo.rs new file mode 100644 index 00000000000..c1e417b97f6 --- /dev/null +++ b/src/test/ui/suggestions/if-let-typo.rs @@ -0,0 +1,9 @@ +fn main() { + let foo = Some(0); + let bar = None; + if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope + if Some(foo) = bar {} //~ ERROR mismatched types + if 3 = foo {} //~ ERROR mismatched types + //~^ ERROR mismatched types + if Some(3) = foo {} //~ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr new file mode 100644 index 00000000000..09db8e01469 --- /dev/null +++ b/src/test/ui/suggestions/if-let-typo.stderr @@ -0,0 +1,60 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/if-let-typo.rs:4:13 + | +LL | if Some(x) = foo {} + | ^ not found in this scope + | +help: you might have meant to use pattern matching + | +LL | if let Some(x) = foo {} + | ^^^ + +error[E0308]: mismatched types + --> $DIR/if-let-typo.rs:5:8 + | +LL | if Some(foo) = bar {} + | ^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | if let Some(foo) = bar {} + | ^^^ +help: you might have meant to compare for equality + | +LL | if Some(foo) == bar {} + | ^^ + +error[E0308]: mismatched types + --> $DIR/if-let-typo.rs:6:12 + | +LL | if 3 = foo {} + | ^^^ expected integer, found enum `std::option::Option` + | + = note: expected type `{integer}` + found enum `std::option::Option<{integer}>` + +error[E0308]: mismatched types + --> $DIR/if-let-typo.rs:6:8 + | +LL | if 3 = foo {} + | ^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/if-let-typo.rs:8:8 + | +LL | if Some(3) = foo {} + | ^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | if let Some(3) = foo {} + | ^^^ +help: you might have meant to compare for equality + | +LL | if Some(3) == foo {} + | ^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs index bc2bf9eca93..01769f71153 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -4,7 +4,7 @@ // Currently, the `type_alias_impl_trait` feature implicitly // depends on `impl_trait_in_bindings` in order to work properly. // Specifically, this line requires `impl_trait_in_bindings` to be enabled: -// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/src/librustc_typeck/check/mod.rs#L856 +// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/compiler/rustc_typeck/check/mod.rs#L856 #![feature(impl_trait_in_bindings)] //~^ WARN the feature `impl_trait_in_bindings` is incomplete diff --git a/src/test/ui/type/type-check/assignment-expected-bool.stderr b/src/test/ui/type/type-check/assignment-expected-bool.stderr index 3f1caddf728..d1c13a33f7f 100644 --- a/src/test/ui/type/type-check/assignment-expected-bool.stderr +++ b/src/test/ui/type/type-check/assignment-expected-bool.stderr @@ -2,100 +2,126 @@ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:6:19 | LL | let _: bool = 0 = 0; - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _: bool = 0 == 0; + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:9:14 | LL | 0 => 0 = 0, - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 => 0 == 0, + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:10:14 | LL | _ => 0 = 0, - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | _ => 0 == 0, + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:14:17 | LL | true => 0 = 0, - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | true => 0 == 0, + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:18:8 | LL | if 0 = 0 {} - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | if let 0 = 0 {} + | ^^^ +help: you might have meant to compare for equality + | +LL | if 0 == 0 {} + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:20:24 | LL | let _: bool = if { 0 = 0 } { - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _: bool = if { 0 == 0 } { + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:21:9 | LL | 0 = 0 - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 == 0 + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:23:9 | LL | 0 = 0 - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 == 0 + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:26:13 | LL | let _ = (0 = 0) - | ^^^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _ = (0 == 0) + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:27:14 | LL | && { 0 = 0 } - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | && { 0 == 0 } + | ^^ error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:28:12 | LL | || (0 = 0); - | ^^^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `0 == 0` + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | || (0 == 0); + | ^^ error[E0070]: invalid left-hand side of assignment --> $DIR/assignment-expected-bool.rs:31:22 diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr index 0957dcb986b..f5306a12264 100644 --- a/src/test/ui/type/type-check/assignment-in-if.stderr +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -2,55 +2,71 @@ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:15:8 | LL | if x = x { - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `x == x` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == x { + | ^^ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:20:8 | LL | if (x = x) { - | ^^^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `x == x` + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if (x == x) { + | ^^ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:25:8 | LL | if y = (Foo { foo: x }) { - | ^^^^^^^^^^^^^^^^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `y == (Foo { foo: x })` + | ^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if y == (Foo { foo: x }) { + | ^^ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:30:8 | LL | if 3 = x { - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `3 == x` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | if let 3 = x { + | ^^^ +help: you might have meant to compare for equality + | +LL | if 3 == x { + | ^^ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:36:13 | LL | x = 4 - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `x == 4` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | x == 4 + | ^^ error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:38:13 | LL | x = 5 - | ^^^^^ - | | - | expected `bool`, found `()` - | help: try comparing for equality: `x == 5` + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | x == 5 + | ^^ error: aborting due to 6 previous errors diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 51b66125ba97d2906f461b3f4e0408f206299bb +Subproject 126907a7cfccbe93778530e6a6bbaa3adb6c515 diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs index 7b419431c0f..3c3f8b26e3a 100644 --- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs @@ -191,7 +191,7 @@ pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool { (Item(l), Item(r)) => eq_item(l, r, eq_item_kind), (Expr(l), Expr(r)) | (Semi(l), Semi(r)) => eq_expr(l, r), (Empty, Empty) => true, - (MacCall(l), MacCall(r)) => l.1 == r.1 && eq_mac_call(&l.0, &r.0) && over(&l.2, &r.2, |l, r| eq_attr(l, r)), + (MacCall(l), MacCall(r)) => l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)), _ => false, } } diff --git a/src/tools/clippy/tests/ui/issue-3145.rs b/src/tools/clippy/tests/ui/issue-3145.rs index f497d5550af..586d13647d1 100644 --- a/src/tools/clippy/tests/ui/issue-3145.rs +++ b/src/tools/clippy/tests/ui/issue-3145.rs @@ -1,3 +1,3 @@ fn main() { - println!("{}" a); //~ERROR expected token: `,` + println!("{}" a); //~ERROR expected `,`, found `a` } diff --git a/src/tools/clippy/tests/ui/issue-3145.stderr b/src/tools/clippy/tests/ui/issue-3145.stderr index cb0d95f5e26..a35032aa150 100644 --- a/src/tools/clippy/tests/ui/issue-3145.stderr +++ b/src/tools/clippy/tests/ui/issue-3145.stderr @@ -1,7 +1,7 @@ -error: expected token: `,` +error: expected `,`, found `a` --> $DIR/issue-3145.rs:2:19 | -LL | println!("{}" a); //~ERROR expected token: `,` +LL | println!("{}" a); //~ERROR expected `,`, found `a` | ^ expected `,` error: aborting due to previous error diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs index efa4177d1d8..caae8c61178 100644 --- a/src/tools/error_index_generator/build.rs +++ b/src/tools/error_index_generator/build.rs @@ -9,7 +9,7 @@ fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let dest = out_dir.join("error_codes.rs"); - let error_codes_path = "../../../src/librustc_error_codes/error_codes.rs"; + let error_codes_path = "../../../compiler/rustc_error_codes/src/error_codes.rs"; println!("cargo:rerun-if-changed={}", error_codes_path); let file = fs::read_to_string(error_codes_path) @@ -19,7 +19,7 @@ fn main() { fs::write(&out_dir.join("all_error_codes.rs"), &contents).unwrap(); // We copy the md files as well to the target directory. - for entry in WalkDir::new("../../../src/librustc_error_codes/error_codes") { + for entry in WalkDir::new("../../../compiler/rustc_error_codes/src/error_codes") { let entry = entry.unwrap(); match entry.path().extension() { Some(s) if s == "md" => {} diff --git a/src/tools/miri b/src/tools/miri -Subproject c2a2e25d0b050d70d6a355f9b7545a991fc8783 +Subproject c28a8eeb742d7104bc407e12212c5143439963f diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer -Subproject e65d48d1fb3d4d91d9dc1148a7a836ff5c9a3c8 +Subproject ac4b134c6be27642dbe915f32a41f9a21bd0c1c diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs index 408be83b926..ab87230f888 100644 --- a/src/tools/tidy/src/debug_artifacts.rs +++ b/src/tools/tidy/src/debug_artifacts.rs @@ -1,4 +1,4 @@ -//! Tidy check to prevent creation of unnecessary debug artifacts. +//! Tidy check to prevent creation of unnecessary debug artifacts while running tests. use std::path::{Path, PathBuf}; diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs index 4a2e49fd1c3..7761ae64ee0 100644 --- a/src/tools/tidy/src/edition.rs +++ b/src/tools/tidy/src/edition.rs @@ -1,5 +1,4 @@ //! Tidy check to ensure that crate `edition` is '2018' -//! use std::path::Path; diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 678e346bd4f..d8029ea04f0 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -71,8 +71,14 @@ pub fn collect_lib_features(base_src_path: &Path) -> Features { lib_features } -pub fn check(src_path: &Path, lib_path: &Path, bad: &mut bool, verbose: bool) -> CollectedFeatures { - let mut features = collect_lang_features(src_path, bad); +pub fn check( + src_path: &Path, + compiler_path: &Path, + lib_path: &Path, + bad: &mut bool, + verbose: bool, +) -> CollectedFeatures { + let mut features = collect_lang_features(compiler_path, bad); assert!(!features.is_empty()); let lib_features = get_and_check_lib_features(lib_path, bad, &features); @@ -225,15 +231,15 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool { false } -pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features { - let mut all = collect_lang_features_in(base_src_path, "active.rs", bad); - all.extend(collect_lang_features_in(base_src_path, "accepted.rs", bad)); - all.extend(collect_lang_features_in(base_src_path, "removed.rs", bad)); +pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features { + let mut all = collect_lang_features_in(base_compiler_path, "active.rs", bad); + all.extend(collect_lang_features_in(base_compiler_path, "accepted.rs", bad)); + all.extend(collect_lang_features_in(base_compiler_path, "removed.rs", bad)); all } fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features { - let path = base.join("librustc_feature").join(file); + let path = base.join("rustc_feature").join("src").join(file); let contents = t!(fs::read_to_string(&path)); // We allow rustc-internal features to omit a tracking issue. diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 43105188ec4..36c9e58eb9a 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -11,44 +11,53 @@ use std::path::PathBuf; use std::process; fn main() { - let path: PathBuf = env::args_os().nth(1).expect("need path to src").into(); + let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into(); let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into(); - let library_path: PathBuf = path - .join("..") - .join("library") - .canonicalize() - .expect("unable to canonicalize path to library/"); + let src_path = root_path.join("src"); + let library_path = root_path.join("library"); + let compiler_path = root_path.join("compiler"); let args: Vec<String> = env::args().skip(1).collect(); let mut bad = false; let verbose = args.iter().any(|s| *s == "--verbose"); + // Checks over tests. + debug_artifacts::check(&src_path, &mut bad); + ui_tests::check(&src_path, &mut bad); + // Checks that only make sense for the compiler. - debug_artifacts::check(&path, &mut bad); - errors::check(&path, &mut bad); - ui_tests::check(&path, &mut bad); - error_codes_check::check(&path, &mut bad); + errors::check(&compiler_path, &mut bad); + error_codes_check::check(&src_path, &mut bad); // Checks that only make sense for the std libs. pal::check(&library_path, &mut bad); unit_tests::check(&library_path, &mut bad); - // Check that need to be done for both the compiler and std libraries. - bins::check(&path, &mut bad); + // Checks that need to be done for both the compiler and std libraries. + bins::check(&src_path, &mut bad); + bins::check(&compiler_path, &mut bad); bins::check(&library_path, &mut bad); - style::check(&path, &mut bad); + + style::check(&src_path, &mut bad); + style::check(&compiler_path, &mut bad); style::check(&library_path, &mut bad); - cargo::check(&path, &mut bad); + + cargo::check(&src_path, &mut bad); + cargo::check(&compiler_path, &mut bad); cargo::check(&library_path, &mut bad); - edition::check(&path, &mut bad); + + edition::check(&src_path, &mut bad); + edition::check(&compiler_path, &mut bad); edition::check(&library_path, &mut bad); - let collected = features::check(&path, &library_path, &mut bad, verbose); - unstable_book::check(&path, collected, &mut bad); - deps::check(&path.parent().unwrap(), &cargo, &mut bad); - extdeps::check(&path.parent().unwrap(), &mut bad); + let collected = features::check(&src_path, &compiler_path, &library_path, &mut bad, verbose); + unstable_book::check(&src_path, collected, &mut bad); + + // Checks that are done on the cargo workspace. + deps::check(&root_path, &cargo, &mut bad); + extdeps::check(&root_path, &mut bad); if bad { eprintln!("some tidy checks failed"); diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 8f9d6915790..1dba6b73b93 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -56,9 +56,14 @@ const EXCEPTION_PATHS: &[&str] = &[ // Integration test for platform-specific run-time feature detection: "library/std/tests/run-time-detect.rs", "library/std/src/net/test.rs", + "library/std/src/net/addr", + "library/std/src/net/udp", "library/std/src/sys_common/mod.rs", "library/std/src/sys_common/net.rs", "library/std/src/sys_common/backtrace.rs", + "library/std/src/sys_common/remutex.rs", + "library/std/src/sync/mutex.rs", + "library/std/src/sync/rwlock.rs", // panic_unwind shims "library/std/src/panicking.rs", "library/term", // Not sure how to make this crate portable, but test crate needs it. diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index c6d67844a2b..04f2bbaa0d9 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -20,15 +20,19 @@ pub fn check(root_path: &Path, bad: &mut bool) { let mut skip = |path: &Path| { let file_name = path.file_name().unwrap_or_default(); if path.is_dir() { - super::filter_dirs(path) || - path.ends_with("src/test") || - path.ends_with("src/doc") || - path.ends_with("library/std") || // FIXME? - (file_name == "tests" || file_name == "benches") && !is_core(path) + super::filter_dirs(path) + || path.ends_with("src/test") + || path.ends_with("src/doc") + || (file_name == "tests" || file_name == "benches") && !is_core(path) } else { let extension = path.extension().unwrap_or_default(); extension != "rs" || (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path) + // UI tests with different names + || path.ends_with("src/thread/local/dynamic_tests.rs") + || path.ends_with("src/sync/mpsc/sync_tests.rs") + // Has copyright banner + || path.ends_with("src/sys/cloudabi/abi/cloudabi.rs") } }; diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 5d277e1c41f..387b2acd106 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -94,14 +94,16 @@ fn copy_recursive(from: &Path, to: &Path) { } fn main() { - let library_path_str = env::args_os().nth(1).expect("library path required"); - let src_path_str = env::args_os().nth(2).expect("source path required"); - let dest_path_str = env::args_os().nth(3).expect("destination path required"); + let library_path_str = env::args_os().nth(1).expect("library/ path required"); + let compiler_path_str = env::args_os().nth(2).expect("compiler/ path required"); + let src_path_str = env::args_os().nth(3).expect("src/ path required"); + let dest_path_str = env::args_os().nth(4).expect("destination path required"); let library_path = Path::new(&library_path_str); + let compiler_path = Path::new(&compiler_path_str); let src_path = Path::new(&src_path_str); let dest_path = Path::new(&dest_path_str); - let lang_features = collect_lang_features(src_path, &mut false); + let lang_features = collect_lang_features(compiler_path, &mut false); let lib_features = collect_lib_features(library_path) .into_iter() .filter(|&(ref name, _)| !lang_features.contains_key(name)) |
